From 8c7b4c7de3c5e90e1165c2eb5eb058242d9f7dec Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 26 Feb 2021 03:37:03 -0800 Subject: Moves the BSD queue to a wrapper to keep it out of the public API --- src/H5FD.c | 40 ++++++++++++++++++++++++++++------------ src/H5FDpublic.h | 15 +++++++-------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 602b198..f34a2ec 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -54,6 +54,11 @@ /* Package Typedefs */ /********************/ +/* H5FD wrapper for VFD SWMR. Allows use as a BSD TAILQ element. */ +typedef struct H5FD_wrap_t { + TAILQ_ENTRY(H5FD_wrap_t) link; /* Linkage for list of all VFDs. */ + H5FD_t *file; /* Pointer to wrapped VFD struct */ +} H5FD_wrap_t; /********************/ /* Local Prototypes */ @@ -92,7 +97,7 @@ hbool_t H5_PKG_INIT_VAR = FALSE; */ static unsigned long H5FD_file_serial_no_g; -static TAILQ_HEAD(_all_vfds, H5FD_t) all_vfds = TAILQ_HEAD_INITIALIZER(all_vfds); +static TAILQ_HEAD(_all_vfds, H5FD_wrap_t) all_vfds = TAILQ_HEAD_INITIALIZER(all_vfds); /* File driver ID class */ static const H5I_class_t H5I_VFL_CLS[1] = {{ @@ -726,18 +731,19 @@ H5FD_dedup(H5FD_t *self, H5FD_t *other, hid_t fapl) H5FD_t * H5FD_deduplicate(H5FD_t *file, hid_t fapl) { - H5FD_t *deduped = file, *item; + H5FD_t *deduped = file; + H5FD_wrap_t *item; TAILQ_FOREACH(item, &all_vfds, link) { /* skip "self" */ - if (item == file) + if (item->file == file) continue; /* skip files with exclusive owners, for now */ - if (item->exc_owner != NULL) + if (item->file->exc_owner != NULL) continue; - if ((deduped = H5FD_dedup(item, file, fapl)) != file) + if ((deduped = H5FD_dedup(item->file, file, fapl)) != file) goto finish; } @@ -746,10 +752,10 @@ H5FD_deduplicate(H5FD_t *file, hid_t fapl) * return NULL to indicate the conflict. */ TAILQ_FOREACH(item, &all_vfds, link) { - if (item == file || item->exc_owner == NULL) + if (item->file == file || item->file->exc_owner == NULL) continue; - if (H5FDcmp(file, item) == 0) { + if (H5FDcmp(file, item->file) == 0) { deduped = NULL; break; } @@ -784,6 +790,7 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) H5P_genplist_t *plist; /* Property list pointer */ unsigned long driver_flags = 0; /* File-inspecific driver feature flags */ H5FD_file_image_info_t file_image_info; /* Initial file image */ + H5FD_wrap_t *swmr_wrapper = NULL; /* H5FD wrapper for SWMR queue */ H5FD_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(NULL) @@ -862,7 +869,11 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) /* (This will be changed later, when the superblock is located) */ file->base_addr = 0; - TAILQ_INSERT_TAIL(&all_vfds, file, link); + /* Create and insert a SWMR wrapper for the file */ + if(NULL == (swmr_wrapper = H5MM_calloc(sizeof(H5FD_wrap_t)))) + HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, NULL, "unable to allocate file wrap struct") + swmr_wrapper->file = file; + TAILQ_INSERT_TAIL(&all_vfds, swmr_wrapper, link); /* Set return value */ ret_value = file; @@ -923,7 +934,8 @@ herr_t H5FD_close(H5FD_t *file) { const H5FD_class_t *driver; - H5FD_t *item; + H5FD_wrap_t *item; + H5FD_wrap_t *delete_me = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) @@ -938,10 +950,14 @@ H5FD_close(H5FD_t *file) HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID") TAILQ_FOREACH(item, &all_vfds, link) { - if (item->exc_owner == file) - item->exc_owner = NULL; + if (item->file->exc_owner == file) + item->file->exc_owner = NULL; + if (item->file == file) + delete_me = item; } - TAILQ_REMOVE(&all_vfds, file, link); + HDassert(delete_me); + TAILQ_REMOVE(&all_vfds, delete_me, link); + H5MM_xfree(delete_me); /* Dispatch to the driver for actual close. If the driver fails to * close the file then the file will be in an unusable state. diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index a921c29..6b2b36e 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -319,19 +319,18 @@ typedef struct H5FD_free_t { * are declared here and the driver appends private fields in memory. */ struct H5FD_t { - hid_t driver_id; /*driver ID for this file */ - const H5FD_class_t *cls; /*constant class info */ - - TAILQ_ENTRY(H5FD_t) link; /* Linkage for list of all VFs. */ - H5FD_t *exc_owner; /* Pointer to an exclusive owner - * or NULL if none. - */ - unsigned long fileno; /* File 'serial' number */ + hid_t driver_id; /* Driver ID for this file */ + const H5FD_class_t *cls; /* Constant class info */ + unsigned long fileno; /* File 'serial' number */ unsigned access_flags; /* File access flags (from create or open) */ unsigned long feature_flags; /* VFL Driver feature Flags */ haddr_t maxaddr; /* For this file, overrides class */ haddr_t base_addr; /* Base address for HDF5 data w/in file */ + H5FD_t *exc_owner; /* Pointer to an exclusive owner + * or NULL if none. + */ + /* Space allocation management fields */ hsize_t threshold; /* Threshold for alignment */ hsize_t alignment; /* Allocation alignment */ -- cgit v0.12 From ba5808196ed2a0e217f65f156ffbd659ad188348 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 26 Feb 2021 10:03:54 -0800 Subject: Moves H5queue.h from H5FDpublic.h to H5FD.c --- src/H5FD.c | 1 + src/H5FDpublic.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5FD.c b/src/H5FD.c index f34a2ec..3587eb7 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -39,6 +39,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ +#include "H5queue.h" /****************/ /* Local Macros */ diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index 6b2b36e..520668b 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -18,7 +18,6 @@ #ifndef _H5FDpublic_H #define _H5FDpublic_H -#include "H5queue.h" #include "H5public.h" #include "H5Fpublic.h" /*for H5F_close_degree_t */ -- cgit v0.12 From 90bfcb9fba276158b26b072402803af6f20c7366 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 26 Feb 2021 10:39:46 -0800 Subject: Moves H5queue.h to H5private.h and yanks circular queue macros --- src/H5FD.c | 1 - src/H5Fpkg.h | 3 - src/H5MF.c | 1 - src/H5private.h | 7 ++ src/H5queue.h | 194 +------------------------------------------------------- 5 files changed, 10 insertions(+), 196 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 3587eb7..f34a2ec 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -39,7 +39,6 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#include "H5queue.h" /****************/ /* Local Macros */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 71d0ce4..260a25c 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -26,9 +26,6 @@ #ifndef _H5Fpkg_H #define _H5Fpkg_H -/* BSD queue macros */ -#include "H5queue.h" - /* Get package's private header */ #include "H5Fprivate.h" diff --git a/src/H5MF.c b/src/H5MF.c index 22438d3..e53496b 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -22,7 +22,6 @@ *------------------------------------------------------------------------- */ -#include "H5queue.h" #include "hlog.h" /****************/ diff --git a/src/H5private.h b/src/H5private.h index 3e11b4f..702b0dc 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -164,6 +164,13 @@ #include #endif +/* BSD-style queues + * + * We use a private copy of netBSD's queues instead of including sys/queue.h + * due to irreconcilable differences between different queue implementations. + */ +#include "H5queue.h" + /* Define the default VFD for this platform. * Since the removal of the Windows VFD, this is sec2 for all platforms. */ diff --git a/src/H5queue.h b/src/H5queue.h index 816acca..e203fcb 100644 --- a/src/H5queue.h +++ b/src/H5queue.h @@ -31,8 +31,8 @@ * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ +#ifndef _H5queue_H_ +#define _H5queue_H_ /* * This file defines five types of data structures: singly-linked lists, @@ -656,192 +656,4 @@ struct { \ ((struct type *)(void *) \ ((char *)((head)->stqh_last) - offsetof(struct type, field)))) - -#ifndef _KERNEL -/* - * Circular queue definitions. Do not use. We still keep the macros - * for compatibility but because of pointer aliasing issues their use - * is discouraged! - */ - -/* - * __launder_type(): We use this ugly hack to work around the the compiler - * noticing that two types may not alias each other and elide tests in code. - * We hit this in the CIRCLEQ macros when comparing 'struct name *' and - * 'struct type *' (see CIRCLEQ_HEAD()). Modern compilers (such as GCC - * 4.8) declare these comparisons as always false, causing the code to - * not run as designed. - * - * This hack is only to be used for comparisons and thus can be fully const. - * Do not use for assignment. - * - * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix - * this by changing the head/tail sentinal values, but see the note above - * this one. - */ -static __inline const void * __launder_type(const void *); -static __inline const void * -__launder_type(const void *__x) -{ - __asm __volatile("" : "+r" (__x)); - return __x; -} - -#if defined(QUEUEDEBUG) -#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \ - if ((head)->cqh_first != CIRCLEQ_ENDC(head) && \ - (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head)) \ - QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head), \ - __FILE__, __LINE__); \ - if ((head)->cqh_last != CIRCLEQ_ENDC(head) && \ - (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head)) \ - QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head), \ - __FILE__, __LINE__); -#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \ - if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) { \ - if ((head)->cqh_last != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } else { \ - if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } \ - if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) { \ - if ((head)->cqh_first != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } else { \ - if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \ - QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d", \ - (elm), __FILE__, __LINE__); \ - } -#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \ - (elm)->field.cqe_next = (void *)1L; \ - (elm)->field.cqe_prev = (void *)1L; -#else -#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) -#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) -#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) -#endif - -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = CIRCLEQ_END(head); \ - (head)->cqh_last = CIRCLEQ_END(head); \ -} while (/*CONSTCOND*/0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ - QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == CIRCLEQ_ENDC(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ - QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == CIRCLEQ_ENDC(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (/*CONSTCOND*/0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = CIRCLEQ_END(head); \ - if ((head)->cqh_last == CIRCLEQ_ENDC(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ - (elm)->field.cqe_next = CIRCLEQ_END(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == CIRCLEQ_ENDC(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (/*CONSTCOND*/0) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ - QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \ - if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ - QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field) \ -} while (/*CONSTCOND*/0) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for ((var) = ((head)->cqh_first); \ - (var) != CIRCLEQ_ENDC(head); \ - (var) = ((var)->field.cqe_next)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for ((var) = ((head)->cqh_last); \ - (var) != CIRCLEQ_ENDC(head); \ - (var) = ((var)->field.cqe_prev)) - -/* - * Circular queue access methods. - */ -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -/* For comparisons */ -#define CIRCLEQ_ENDC(head) (__launder_type(head)) -/* For assignments */ -#define CIRCLEQ_END(head) ((void *)(head)) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) -#define CIRCLEQ_EMPTY(head) \ - (CIRCLEQ_FIRST(head) == CIRCLEQ_ENDC(head)) - -#define CIRCLEQ_LOOP_NEXT(head, elm, field) \ - (((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) \ - ? ((head)->cqh_first) \ - : (elm->field.cqe_next)) -#define CIRCLEQ_LOOP_PREV(head, elm, field) \ - (((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) \ - ? ((head)->cqh_last) \ - : (elm->field.cqe_prev)) -#endif /* !_KERNEL */ - -#endif /* !_SYS_QUEUE_H_ */ +#endif /* _H5queue_H_ */ -- cgit v0.12 From 0a1444ea78740ce874f2629562d5346b0662658b Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 26 Feb 2021 11:21:49 -0800 Subject: Adapts H5queue.h to work on MacOS --- src/H5queue.h | 223 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 123 insertions(+), 100 deletions(-) diff --git a/src/H5queue.h b/src/H5queue.h index e203fcb..a84ba52 100644 --- a/src/H5queue.h +++ b/src/H5queue.h @@ -34,6 +34,27 @@ #ifndef _H5queue_H_ #define _H5queue_H_ +/* This is a copy of netBSD's sys/queue.h header for use in HDF5. We've copied + * it here instead of using the system's version to avoid incompatibilities. + * The exception is MacOS, where other system headers make use of sys/queue.h + * (this may also be an issue on FreeBSD, et al.). + * + * The deprecated and unwise circular queue macros have been removed from + * this file to discourage their use. + */ + + +/* On MacOS, sys/file.h (needed for flock(3)) includes sys.queue.h, so we + * can't just use an alternative BSD queue implementation without running + * into symbol redefinition errors. + * + * Unfortunately, MacOS is missing SIMPLEQ, so we have to handle that + * separately later in the file. + */ +#if defined(__APPLE__) +#include +#else + /* * This file defines five types of data structures: singly-linked lists, * lists, simple queues, tail queues, and circular queues. @@ -296,106 +317,6 @@ struct { \ } while (/*CONSTCOND*/0) /* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for ((var) = ((head)->sqh_first); \ - (var) != SIMPLEQ_END(head); \ - (var) = ((var)->field.sqe_next)) - -#define SIMPLEQ_FOREACH_SAFE(var, head, field, next) \ - for ((var) = ((head)->sqh_first); \ - (var) != SIMPLEQ_END(head) && \ - ((next = ((var)->field.sqe_next)), 1); \ - (var) = (next)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ - if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ - == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_REMOVE(head, elm, type, field) do { \ - if ((head)->sqh_first == (elm)) { \ - SIMPLEQ_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->sqh_first; \ - while (curelm->field.sqe_next != (elm)) \ - curelm = curelm->field.sqe_next; \ - if ((curelm->field.sqe_next = \ - curelm->field.sqe_next->field.sqe_next) == NULL) \ - (head)->sqh_last = &(curelm)->field.sqe_next; \ - } \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_CONCAT(head1, head2) do { \ - if (!SIMPLEQ_EMPTY((head2))) { \ - *(head1)->sqh_last = (head2)->sqh_first; \ - (head1)->sqh_last = (head2)->sqh_last; \ - SIMPLEQ_INIT((head2)); \ - } \ -} while (/*CONSTCOND*/0) - -#define SIMPLEQ_LAST(head, type, field) \ - (SIMPLEQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *)(void *) \ - ((char *)((head)->sqh_last) - offsetof(struct type, field)))) - -/* * Tail queue definitions. */ #define _TAILQ_HEAD(name, type, qual) \ @@ -656,4 +577,106 @@ struct { \ ((struct type *)(void *) \ ((char *)((head)->stqh_last) - offsetof(struct type, field)))) +#endif /* defined(__APPLE__) */ + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for ((var) = ((head)->sqh_first); \ + (var) != SIMPLEQ_END(head); \ + (var) = ((var)->field.sqe_next)) + +#define SIMPLEQ_FOREACH_SAFE(var, head, field, next) \ + for ((var) = ((head)->sqh_first); \ + (var) != SIMPLEQ_END(head) && \ + ((next = ((var)->field.sqe_next)), 1); \ + (var) = (next)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ + if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ + == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_REMOVE(head, elm, type, field) do { \ + if ((head)->sqh_first == (elm)) { \ + SIMPLEQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->sqh_first; \ + while (curelm->field.sqe_next != (elm)) \ + curelm = curelm->field.sqe_next; \ + if ((curelm->field.sqe_next = \ + curelm->field.sqe_next->field.sqe_next) == NULL) \ + (head)->sqh_last = &(curelm)->field.sqe_next; \ + } \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_CONCAT(head1, head2) do { \ + if (!SIMPLEQ_EMPTY((head2))) { \ + *(head1)->sqh_last = (head2)->sqh_first; \ + (head1)->sqh_last = (head2)->sqh_last; \ + SIMPLEQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_LAST(head, type, field) \ + (SIMPLEQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->sqh_last) - offsetof(struct type, field)))) + #endif /* _H5queue_H_ */ -- cgit v0.12 From 0e9f9a280af0e4944c18996beb6e110f48fe841e Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 26 Feb 2021 11:34:53 -0800 Subject: Adds MacOS work-around for sigtimedwait(2) in the VFD SWMR tests --- configure.ac | 132 +++++++++++++++++++++++-------------------------- test/vfd_swmr_common.c | 85 ++++++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 70 deletions(-) diff --git a/configure.ac b/configure.ac index 6d869f9..2307b4a 100644 --- a/configure.ac +++ b/configure.ac @@ -1750,84 +1750,78 @@ esac if test "X$THREADSAFE" = "Xyes"; then AC_DEFINE([HAVE_THREADSAFE], [1], [Define if we have thread safe support]) +fi - ## ---------------------------------------------------------------------- - ## Is the Pthreads library present? It has a header file `pthread.h' and - ## a library `-lpthread' and their locations might be specified with the - ## `--with-pthread' command-line switch. The value is an include path - ## and/or a library path. If the library path is specified then it must - ## be preceded by a comma. - ## - ## Thread-safety in HDF5 only uses Pthreads via configure, so the - ## default is "check", though this only has an effect when - ## --enable-threadsafe is specified. - AC_SUBST([HAVE_PTHREAD]) HAVE_PTHREAD=yes - AC_ARG_WITH([pthread], - [AS_HELP_STRING([--with-pthread=DIR], - [Specify alternative path to Pthreads library when - thread-safe capability is built.])],, - [withval=check]) +## ---------------------------------------------------------------------- +## Is the Pthreads library present? It has a header file `pthread.h' and +## a library `-lpthread' and their locations might be specified with the +## `--with-pthread' command-line switch. The value is an include path +## and/or a library path. If the library path is specified then it must +## be preceded by a comma. +AC_SUBST([HAVE_PTHREAD]) + +AC_ARG_WITH([pthread], + [AS_HELP_STRING([--with-pthread=DIR], + [Specify alternative path to Pthreads library when + thread-safe capability is built.])],, + [withval=check]) +case "$withval" in + check | yes) + AC_CHECK_HEADERS([pthread.h],,) + AC_CHECK_LIB([pthread], [pthread_self]) + ;; + no) + AC_MSG_RESULT([suppressed]) + ;; + *) case "$withval" in - check | yes) - AC_CHECK_HEADERS([pthread.h],, [unset HAVE_PTHREAD]) - if test "x$HAVE_PTHREAD" = "xyes"; then - AC_CHECK_LIB([pthread], [pthread_self],, [unset HAVE_PTHREAD]) - fi - ;; - no) - AC_MSG_ERROR([Must use Pthreads with thread safety]) + *,*) + pthread_inc="`echo $withval | cut -f1 -d,`" + pthread_lib="`echo $withval | cut -f2 -d, -s`" ;; *) - case "$withval" in - *,*) - pthread_inc="`echo $withval | cut -f1 -d,`" - pthread_lib="`echo $withval | cut -f2 -d, -s`" - ;; - *) - if test -n "$withval"; then - pthread_inc="$withval/include" - pthread_lib="$withval/lib" - fi - ;; - esac - - if test -n "$pthread_inc"; then - saved_CPPFLAGS="$CPPFLAGS" - saved_AM_CPPFLAGS="$AM_CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$pthread_inc" - AM_CPPFLAGS="$AM_CPPFLAGS -I$pthread_inc" - AC_CHECK_HEADERS([pthread.h],, [CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS"; unset HAVE_PTHREAD]) - else - AC_CHECK_HEADERS([pthread.h],, [unset HAVE_PTHREAD]) - fi - - if test "x$HAVE_PTHREAD" = "xyes"; then - if test -n "$pthread_lib"; then - saved_LDFLAGS="$LDFLAGS" - saved_AM_LDFLAGS="$AM_LDFLAGS" - LDFLAGS="$LDFLAGS -L$pthread_lib" - AM_LDFLAGS="$AM_LDFLAGS -L$pthread_lib" - AC_CHECK_LIB([pthread], [pthread_self],, - [LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset HAVE_PTHREAD]) - else - AC_CHECK_LIB([pthread], [pthread_self],, [unset HAVE_PTHREAD]) - fi + if test -n "$withval"; then + pthread_inc="$withval/include" + pthread_lib="$withval/lib" fi ;; esac - ## ---------------------------------------------------------------------- - ## Check if pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM) - ## is supported on this system - ## - ## Unfortunately, this probably needs to be an AC_RUN_IFELSE since - ## it's impossible to determine if PTHREAD_SCOPE_SYSTEM is - ## supported a priori. POSIX.1-2001 requires that a conformant - ## system need only support one of SYSTEM or PROCESS scopes. - ## - ## For cross-compiling, we've added a pessimistic 'no'. You can - ## hand-hack the config file if you know otherwise. + if test -n "$pthread_inc"; then + saved_CPPFLAGS="$CPPFLAGS" + saved_AM_CPPFLAGS="$AM_CPPFLAGS" + CPPFLAGS="$CPPFLAGS -I$pthread_inc" + AM_CPPFLAGS="$AM_CPPFLAGS -I$pthread_inc" + AC_CHECK_HEADERS([pthread.h],,[CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS";]) + else + AC_CHECK_HEADERS([pthread.h]) + fi + + if test -n "$pthread_lib"; then + saved_LDFLAGS="$LDFLAGS" + saved_AM_LDFLAGS="$AM_LDFLAGS" + LDFLAGS="$LDFLAGS -L$pthread_lib" + AM_LDFLAGS="$AM_LDFLAGS -L$pthread_lib" + AC_CHECK_LIB([pthread], [pthread_self],,[LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS";]) + else + AC_CHECK_LIB([pthread], [pthread_self]) + fi + ;; +esac + +## ---------------------------------------------------------------------- +## Check if pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM) +## is supported on this system +## +## Unfortunately, this probably needs to be an AC_RUN_IFELSE since +## it's impossible to determine if PTHREAD_SCOPE_SYSTEM is +## supported a priori. POSIX.1-2001 requires that a conformant +## system need only support one of SYSTEM or PROCESS scopes. +## +## For cross-compiling, we've added a pessimistic 'no'. You can +## hand-hack the config file if you know otherwise. +if test "x$HAVE_PTHREAD" = "xyes"; then AC_MSG_CHECKING([Pthreads supports system scope]) AC_CACHE_VAL([hdf5_cv_system_scope_threads], [AC_RUN_IFELSE( diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index 043b7ed..d4bb8ef 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -20,6 +20,9 @@ /***********/ #include /* for err(3) */ +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif #include "h5test.h" #include "vfd_swmr_common.h" @@ -178,6 +181,55 @@ strsignal(int signum) } #endif +#if defined(__APPLE__) && defined(__MACH__) + +typedef struct timer_params_t { + struct timespec *tick; + hid_t fid; +} timer_params_t; + +pthread_mutex_t timer_mutex; +hbool_t timer_stop = FALSE; + +static void * +timer_function(void *arg) +{ + timer_params_t *params = (timer_params_t *)arg; + sigset_t sleepset; + hbool_t done = FALSE; + + /* Ignore any signals */ + sigfillset(&sleepset); + pthread_sigmask(SIG_SETMASK, &sleepset, NULL); + + for (;;) { + estack_state_t es; + + nanosleep(params->tick, NULL); + + /* Check the mutex */ + pthread_mutex_lock(&timer_mutex); + done = timer_stop; + pthread_mutex_unlock(&timer_mutex); + if (done) + break; + + /* Avoid deadlock with peer: periodically enter the API so that + * tick processing occurs and data is flushed so that the peer + * can see it. + * + * The call we make will fail, but that's ok, + * so squelch errors. + */ + es = disable_estack(); + (void)H5Aexists_by_name(params->fid, "nonexistent", "nonexistent", H5P_DEFAULT); + restore_estack(es); + } + + return NULL; +} +#endif + /* Wait for any signal to occur and then return. Wake periodically * during the wait to perform API calls: in this way, the * VFD SWMR tick number advances and recent changes do not languish @@ -186,8 +238,8 @@ strsignal(int signum) void await_signal(hid_t fid) { - sigset_t sleepset; struct timespec tick = {.tv_sec = 0, .tv_nsec = 1000000000 / 100}; + sigset_t sleepset; if (sigfillset(&sleepset) == -1) { err(EXIT_FAILURE, "%s.%d: could not initialize signal mask", @@ -202,7 +254,37 @@ await_signal(hid_t fid) dbgf(1, "waiting for signal\n"); +#if defined(__APPLE__) && defined(__MACH__) + { + /* MacOS does not have sigtimedwait(2), so use an alternative. + * XXX: Replace with configure macros later. + */ + timer_params_t params; + int rc; + pthread_t timer; + + params.tick = &tick; + params.fid = fid; + + pthread_mutex_init(&timer_mutex, NULL); + + pthread_create(&timer, NULL, timer_function, ¶ms); + + rc = sigwait(&sleepset, NULL); + + if (rc != -1) { + fprintf(stderr, "Received signal, wrapping things up.\n"); + pthread_mutex_lock(&timer_mutex); + timer_stop = TRUE; + pthread_mutex_unlock(&timer_mutex); + pthread_join(timer, NULL); + } + else + err(EXIT_FAILURE, "%s: sigtimedwait", __func__); + } +#else for (;;) { + /* Linux and other systems */ const int rc = sigtimedwait(&sleepset, NULL, &tick); if (rc != -1) { @@ -226,6 +308,7 @@ await_signal(hid_t fid) } else if (rc == -1) err(EXIT_FAILURE, "%s: sigtimedwait", __func__); } +#endif } /* Revised support routines that can be used for all VFD SWMR integration tests -- cgit v0.12 From f6e7edcedf0339bd18ca0a995f9877a778180f5f Mon Sep 17 00:00:00 2001 From: vchoi Date: Fri, 26 Feb 2021 13:54:11 -0600 Subject: Add the two VFD SWMR demo programs to the test directory so that they can be built as needed. --- MANIFEST | 1 + configure.ac | 10 + m4/ax_with_curses.m4 | 571 +++++++++++++++++++++++++++++++++++ test/Makefile.am | 16 +- test/vfd_swmr_common.c | 19 ++ test/vfd_swmr_common.h | 9 + test/vfd_swmr_credel.c | 483 +++++++++++++++++++++++++++++ test/vfd_swmr_gaussians.c | 753 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1861 insertions(+), 1 deletion(-) create mode 100644 m4/ax_with_curses.m4 create mode 100644 test/vfd_swmr_credel.c create mode 100644 test/vfd_swmr_gaussians.c diff --git a/MANIFEST b/MANIFEST index 4b14d3f..d493763 100644 --- a/MANIFEST +++ b/MANIFEST @@ -56,6 +56,7 @@ ./m4/ax_prog_javah.m4 ./m4/ax_try_compile_java.m4 ./m4/ax_try_run_java.m4 +./m4/ax_with_curses.m4 ./bin/COPYING ./bin/bbrelease _DO_NOT_DISTRIBUTE_ diff --git a/configure.ac b/configure.ac index 6d869f9..d7a29fd 100644 --- a/configure.ac +++ b/configure.ac @@ -1439,6 +1439,15 @@ case "X-$withval" in esac ## ---------------------------------------------------------------------- +## Check if the CURSES library is present. +## This is required to build one of the VFD SWMR demo program. +## +AX_WITH_CURSES +if test "x$ax_cv_curses" != xyes; then + AC_MSG_ERROR([A curses library is required to build the VFD SWMR demo: vfd_swmr_gaussians]) +fi + +## ---------------------------------------------------------------------- ## Make the external filters list available to *.in files ## At this point it's unset (no external filters by default) but it ## will be filled in during the deflate (zlib) and szip processing @@ -3734,6 +3743,7 @@ 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"]) + ## ---------------------------------------------------------------------- ## Build the Makefiles. ## diff --git a/m4/ax_with_curses.m4 b/m4/ax_with_curses.m4 new file mode 100644 index 0000000..945a626 --- /dev/null +++ b/m4/ax_with_curses.m4 @@ -0,0 +1,571 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_with_curses.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_WITH_CURSES +# +# DESCRIPTION +# +# This macro checks whether a SysV or X/Open-compatible Curses library is +# present, along with the associated header file. The NcursesW +# (wide-character) library is searched for first, followed by Ncurses, +# then the system-default plain Curses. The first library found is the +# one returned. Finding libraries will first be attempted by using +# pkg-config, and should the pkg-config files not be available, will +# fallback to combinations of known flags itself. +# +# The following options are understood: --with-ncursesw, --with-ncurses, +# --without-ncursesw, --without-ncurses. The "--with" options force the +# macro to use that particular library, terminating with an error if not +# found. The "--without" options simply skip the check for that library. +# The effect on the search pattern is: +# +# (no options) - NcursesW, Ncurses, Curses +# --with-ncurses --with-ncursesw - NcursesW only [*] +# --without-ncurses --with-ncursesw - NcursesW only [*] +# --with-ncursesw - NcursesW only [*] +# --with-ncurses --without-ncursesw - Ncurses only [*] +# --with-ncurses - NcursesW, Ncurses [**] +# --without-ncurses --without-ncursesw - Curses only +# --without-ncursesw - Ncurses, Curses +# --without-ncurses - NcursesW, Curses +# +# [*] If the library is not found, abort the configure script. +# +# [**] If the second library (Ncurses) is not found, abort configure. +# +# The following preprocessor symbols may be defined by this macro if the +# appropriate conditions are met: +# +# HAVE_CURSES - if any SysV or X/Open Curses library found +# HAVE_CURSES_ENHANCED - if library supports X/Open Enhanced functions +# HAVE_CURSES_COLOR - if library supports color (enhanced functions) +# HAVE_CURSES_OBSOLETE - if library supports certain obsolete features +# HAVE_NCURSESW - if NcursesW (wide char) library is to be used +# HAVE_NCURSES - if the Ncurses library is to be used +# +# HAVE_CURSES_H - if is present and should be used +# HAVE_NCURSESW_H - if should be used +# HAVE_NCURSES_H - if should be used +# HAVE_NCURSESW_CURSES_H - if should be used +# HAVE_NCURSES_CURSES_H - if should be used +# +# (These preprocessor symbols are discussed later in this document.) +# +# The following output variables are defined by this macro; they are +# precious and may be overridden on the ./configure command line: +# +# CURSES_LIBS - library to add to xxx_LDADD +# CURSES_CFLAGS - include paths to add to xxx_CPPFLAGS +# +# In previous versions of this macro, the flags CURSES_LIB and +# CURSES_CPPFLAGS were defined. These have been renamed, in keeping with +# AX_WITH_CURSES's close bigger brother, PKG_CHECK_MODULES, which should +# eventually supersede the use of AX_WITH_CURSES. Neither the library +# listed in CURSES_LIBS, nor the flags in CURSES_CFLAGS are added to LIBS, +# respectively CPPFLAGS, by default. You need to add both to the +# appropriate xxx_LDADD/xxx_CPPFLAGS line in your Makefile.am. For +# example: +# +# prog_LDADD = @CURSES_LIBS@ +# prog_CPPFLAGS = @CURSES_CFLAGS@ +# +# If CURSES_LIBS is set on the configure command line (such as by running +# "./configure CURSES_LIBS=-lmycurses"), then the only header searched for +# is . If the user needs to specify an alternative path for a +# library (such as for a non-standard NcurseW), the user should use the +# LDFLAGS variable. +# +# The following shell variables may be defined by this macro: +# +# ax_cv_curses - set to "yes" if any Curses library found +# ax_cv_curses_enhanced - set to "yes" if Enhanced functions present +# ax_cv_curses_color - set to "yes" if color functions present +# ax_cv_curses_obsolete - set to "yes" if obsolete features present +# +# ax_cv_ncursesw - set to "yes" if NcursesW library found +# ax_cv_ncurses - set to "yes" if Ncurses library found +# ax_cv_plaincurses - set to "yes" if plain Curses library found +# ax_cv_curses_which - set to "ncursesw", "ncurses", "plaincurses" or "no" +# +# These variables can be used in your configure.ac to determine the level +# of support you need from the Curses library. For example, if you must +# have either Ncurses or NcursesW, you could include: +# +# AX_WITH_CURSES +# if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then +# AC_MSG_ERROR([requires either NcursesW or Ncurses library]) +# fi +# +# If any Curses library will do (but one must be present and must support +# color), you could use: +# +# AX_WITH_CURSES +# if test "x$ax_cv_curses" != xyes || test "x$ax_cv_curses_color" != xyes; then +# AC_MSG_ERROR([requires an X/Open-compatible Curses library with color]) +# fi +# +# Certain preprocessor symbols and shell variables defined by this macro +# can be used to determine various features of the Curses library. In +# particular, HAVE_CURSES and ax_cv_curses are defined if the Curses +# library found conforms to the traditional SysV and/or X/Open Base Curses +# definition. Any working Curses library conforms to this level. +# +# HAVE_CURSES_ENHANCED and ax_cv_curses_enhanced are defined if the +# library supports the X/Open Enhanced Curses definition. In particular, +# the wide-character types attr_t, cchar_t and wint_t, the functions +# wattr_set() and wget_wch() and the macros WA_NORMAL and _XOPEN_CURSES +# are checked. The Ncurses library does NOT conform to this definition, +# although NcursesW does. +# +# HAVE_CURSES_COLOR and ax_cv_curses_color are defined if the library +# supports color functions and macros such as COLOR_PAIR, A_COLOR, +# COLOR_WHITE, COLOR_RED and init_pair(). These are NOT part of the +# X/Open Base Curses definition, but are part of the Enhanced set of +# functions. The Ncurses library DOES support these functions, as does +# NcursesW. +# +# HAVE_CURSES_OBSOLETE and ax_cv_curses_obsolete are defined if the +# library supports certain features present in SysV and BSD Curses but not +# defined in the X/Open definition. In particular, the functions +# getattrs(), getcurx() and getmaxx() are checked. +# +# To use the HAVE_xxx_H preprocessor symbols, insert the following into +# your system.h (or equivalent) header file: +# +# #if defined HAVE_NCURSESW_CURSES_H +# # include +# #elif defined HAVE_NCURSESW_H +# # include +# #elif defined HAVE_NCURSES_CURSES_H +# # include +# #elif defined HAVE_NCURSES_H +# # include +# #elif defined HAVE_CURSES_H +# # include +# #else +# # error "SysV or X/Open-compatible Curses header file required" +# #endif +# +# For previous users of this macro: you should not need to change anything +# in your configure.ac or Makefile.am, as the previous (serial 10) +# semantics are still valid. However, you should update your system.h (or +# equivalent) header file to the fragment shown above. You are encouraged +# also to make use of the extended functionality provided by this version +# of AX_WITH_CURSES, as well as in the additional macros +# AX_WITH_CURSES_PANEL, AX_WITH_CURSES_MENU and AX_WITH_CURSES_FORM. +# +# LICENSE +# +# Copyright (c) 2009 Mark Pulford +# Copyright (c) 2009 Damian Pietras +# Copyright (c) 2012 Reuben Thomas +# Copyright (c) 2011 John Zaitseff +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 18 + +# internal function to factorize common code that is used by both ncurses +# and ncursesw +AC_DEFUN([_FIND_CURSES_FLAGS], [ + # THG CHANGES! + # + # In order to avoid a dependency on pkg-conf, that part of this macro + # has been removed. This code always uses the "fallback" option. + + AC_CACHE_CHECK([for $1], [ax_cv_$1], [ + AS_ECHO() + pkg_cv__ax_cv_$1_libs="-l$1" + pkg_cv__ax_cv_$1_cppflags="-D_GNU_SOURCE $CURSES_CFLAGS" + LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs" + CPPFLAGS="$ax_saved_CPPFLAGS $pkg_cv__ax_cv_$1_cppflags" + + AC_MSG_CHECKING([for initscr() with $pkg_cv__ax_cv_$1_libs]) + AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], + [ + AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([for nodelay() with $pkg_cv__ax_cv_$1_libs]) + AC_LINK_IFELSE([AC_LANG_CALL([], [nodelay])],[ + ax_cv_$1=yes + ],[ + AC_MSG_RESULT([no]) + m4_if( + [$1],[ncursesw],[pkg_cv__ax_cv_$1_libs="$pkg_cv__ax_cv_$1_libs -ltinfow"], + [$1],[ncurses],[pkg_cv__ax_cv_$1_libs="$pkg_cv__ax_cv_$1_libs -ltinfo"] + ) + LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs" + + AC_MSG_CHECKING([for nodelay() with $pkg_cv__ax_cv_$1_libs]) + AC_LINK_IFELSE([AC_LANG_CALL([], [nodelay])],[ + ax_cv_$1=yes + ],[ + ax_cv_$1=no + ]) + ]) + ],[ + ax_cv_$1=no + ]) + ]) +]) + +AU_ALIAS([MP_WITH_CURSES], [AX_WITH_CURSES]) +AC_DEFUN([AX_WITH_CURSES], [ + AC_ARG_VAR([CURSES_LIBS], [linker library for Curses, e.g. -lcurses]) + AC_ARG_VAR([CURSES_CFLAGS], [preprocessor flags for Curses, e.g. -I/usr/include/ncursesw]) + AC_ARG_WITH([ncurses], [AS_HELP_STRING([--with-ncurses], + [force the use of Ncurses or NcursesW])], + [], [with_ncurses=check]) + AC_ARG_WITH([ncursesw], [AS_HELP_STRING([--without-ncursesw], + [do not use NcursesW (wide character support)])], + [], [with_ncursesw=check]) + + ax_saved_LIBS=$LIBS + ax_saved_CPPFLAGS=$CPPFLAGS + + AS_IF([test "x$with_ncurses" = xyes || test "x$with_ncursesw" = xyes], + [ax_with_plaincurses=no], [ax_with_plaincurses=check]) + + ax_cv_curses_which=no + + # Test for NcursesW + AS_IF([test "x$CURSES_LIBS" = x && test "x$with_ncursesw" != xno], [ + _FIND_CURSES_FLAGS([ncursesw]) + + AS_IF([test "x$ax_cv_ncursesw" = xno && test "x$with_ncursesw" = xyes], [ + AC_MSG_ERROR([--with-ncursesw specified but could not find NcursesW library]) + ]) + + AS_IF([test "x$ax_cv_ncursesw" = xyes], [ + ax_cv_curses=yes + ax_cv_curses_which=ncursesw + CURSES_LIBS="$pkg_cv__ax_cv_ncursesw_libs" + CURSES_CFLAGS="$pkg_cv__ax_cv_ncursesw_cppflags" + AC_DEFINE([HAVE_NCURSESW], [1], [Define to 1 if the NcursesW library is present]) + AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) + + AC_CACHE_CHECK([for working ncursesw/curses.h], [ax_cv_header_ncursesw_curses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_header_ncursesw_curses_h=yes], + [ax_cv_header_ncursesw_curses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSESW_CURSES_H], [1], [Define to 1 if is present]) + ]) + + AC_CACHE_CHECK([for working ncursesw.h], [ax_cv_header_ncursesw_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_header_ncursesw_h=yes], + [ax_cv_header_ncursesw_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncursesw_h" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSESW_H], [1], [Define to 1 if is present]) + ]) + + AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h_with_ncursesw], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_header_ncurses_h_with_ncursesw=yes], + [ax_cv_header_ncurses_h_with_ncursesw=no]) + ]) + AS_IF([test "x$ax_cv_header_ncurses_h_with_ncursesw" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if is present]) + ]) + + AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xno && test "x$ax_cv_header_ncursesw_h" = xno && test "x$ax_cv_header_ncurses_h_with_ncursesw" = xno], [ + AC_MSG_WARN([could not find a working ncursesw/curses.h, ncursesw.h or ncurses.h]) + ]) + ]) + ]) + unset pkg_cv__ax_cv_ncursesw_libs + unset pkg_cv__ax_cv_ncursesw_cppflags + + # Test for Ncurses + AS_IF([test "x$CURSES_LIBS" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [ + _FIND_CURSES_FLAGS([ncurses]) + + AS_IF([test "x$ax_cv_ncurses" = xno && test "x$with_ncurses" = xyes], [ + AC_MSG_ERROR([--with-ncurses specified but could not find Ncurses library]) + ]) + + AS_IF([test "x$ax_cv_ncurses" = xyes], [ + ax_cv_curses=yes + ax_cv_curses_which=ncurses + CURSES_LIBS="$pkg_cv__ax_cv_ncurses_libs" + CURSES_CFLAGS="$pkg_cv__ax_cv_ncurses_cppflags" + AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if the Ncurses library is present]) + AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) + + AC_CACHE_CHECK([for working ncurses/curses.h], [ax_cv_header_ncurses_curses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + ]])], + [ax_cv_header_ncurses_curses_h=yes], + [ax_cv_header_ncurses_curses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xyes], [ + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSES_CURSES_H], [1], [Define to 1 if is present]) + ]) + + AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + ]])], + [ax_cv_header_ncurses_h=yes], + [ax_cv_header_ncurses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_ncurses_h" = xyes], [ + ax_cv_curses_color=yes + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if is present]) + ]) + + AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xno && test "x$ax_cv_header_ncurses_h" = xno], [ + AC_MSG_WARN([could not find a working ncurses/curses.h or ncurses.h]) + ]) + ]) + ]) + unset pkg_cv__ax_cv_ncurses_libs + unset pkg_cv__ax_cv_ncurses_cppflags + + # Test for plain Curses (or if CURSES_LIBS was set by user) + AS_IF([test "x$with_plaincurses" != xno && test "x$ax_cv_curses_which" = xno], [ + AS_IF([test "x$CURSES_LIBS" != x], [ + LIBS="$ax_saved_LIBS $CURSES_LIBS" + ], [ + LIBS="$ax_saved_LIBS -lcurses" + ]) + + AC_CACHE_CHECK([for Curses library], [ax_cv_plaincurses], [ + AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], + [ax_cv_plaincurses=yes], [ax_cv_plaincurses=no]) + ]) + + AS_IF([test "x$ax_cv_plaincurses" = xyes], [ + ax_cv_curses=yes + ax_cv_curses_which=plaincurses + AS_IF([test "x$CURSES_LIBS" = x], [ + CURSES_LIBS="-lcurses" + ]) + AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) + + # Check for base conformance (and header file) + + AC_CACHE_CHECK([for working curses.h], [ax_cv_header_curses_h], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + initscr(); + ]])], + [ax_cv_header_curses_h=yes], + [ax_cv_header_curses_h=no]) + ]) + AS_IF([test "x$ax_cv_header_curses_h" = xyes], [ + AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if is present]) + + # Check for X/Open Enhanced conformance + + AC_CACHE_CHECK([for X/Open Enhanced Curses conformance], [ax_cv_plaincurses_enhanced], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + @%:@ifndef _XOPEN_CURSES + @%:@error "this Curses library is not enhanced" + "this Curses library is not enhanced" + @%:@endif + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + attr_t d = WA_NORMAL; + cchar_t e; + wint_t f; + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + wattr_set(stdscr, d, 0, NULL); + wget_wch(stdscr, &f); + ]])], + [ax_cv_plaincurses_enhanced=yes], + [ax_cv_plaincurses_enhanced=no]) + ]) + AS_IF([test "x$ax_cv_plaincurses_enhanced" = xyes], [ + ax_cv_curses_enhanced=yes + ax_cv_curses_color=yes + AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + ]) + + # Check for color functions + + AC_CACHE_CHECK([for Curses color functions], [ax_cv_plaincurses_color], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@define _XOPEN_SOURCE_EXTENDED 1 + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + chtype c = COLOR_PAIR(1) & A_COLOR; + initscr(); + init_pair(1, COLOR_WHITE, COLOR_RED); + ]])], + [ax_cv_plaincurses_color=yes], + [ax_cv_plaincurses_color=no]) + ]) + AS_IF([test "x$ax_cv_plaincurses_color" = xyes], [ + ax_cv_curses_color=yes + AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) + ]) + + # Check for obsolete functions + + AC_CACHE_CHECK([for obsolete Curses functions], [ax_cv_plaincurses_obsolete], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + chtype a = A_BOLD; + int b = KEY_LEFT; + int g = getattrs(stdscr); + int h = getcurx(stdscr) + getmaxx(stdscr); + initscr(); + ]])], + [ax_cv_plaincurses_obsolete=yes], + [ax_cv_plaincurses_obsolete=no]) + ]) + AS_IF([test "x$ax_cv_plaincurses_obsolete" = xyes], [ + ax_cv_curses_obsolete=yes + AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) + ]) + ]) + + AS_IF([test "x$ax_cv_header_curses_h" = xno], [ + AC_MSG_WARN([could not find a working curses.h]) + ]) + ]) + ]) + + AS_IF([test "x$ax_cv_curses" != xyes], [ax_cv_curses=no]) + AS_IF([test "x$ax_cv_curses_enhanced" != xyes], [ax_cv_curses_enhanced=no]) + AS_IF([test "x$ax_cv_curses_color" != xyes], [ax_cv_curses_color=no]) + AS_IF([test "x$ax_cv_curses_obsolete" != xyes], [ax_cv_curses_obsolete=no]) + + LIBS=$ax_saved_LIBS + CPPFLAGS=$ax_saved_CPPFLAGS + + unset ax_saved_LIBS + unset ax_saved_CPPFLAGS +])dnl diff --git a/test/Makefile.am b/test/Makefile.am index 2b1d7d5..0aec03c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -120,10 +120,24 @@ endif # --enable-build-all at configure time. # The gen_old_* files can only be compiled with older versions of the library # so do not appear in this list. +# Add the two VFD SWMR demo programs and build it as needed. BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \ gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \ gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \ - gen_sizes_lheap gen_file_image gen_plist gen_bad_offset gen_bounds + gen_sizes_lheap gen_file_image gen_plist gen_bad_offset gen_bounds \ + vfd_swmr_gaussians vfd_swmr_credel + +# VFD SWMR demo: vfd_swmr_gaussians needs the curses library +vfd_swmr_gaussians_LDFLAGS=$(AM_LDFLAGS) @CURSES_LIBS@ +vfd_swmr_gaussians=$(AM_CFLAGS) @CURSES_LIBS@ + +# Writer for VFD SWMR demo +w_vfd_swmr_gaussians: vfd_swmr_gaussians + @test -e w_vfd_swmr_gaussians || ln -s vfd_swmr_gaussians w_vfd_swmr_gaussians + +# Reader for VFD SWMR demo +r_vfd_swmr_gaussians: vfd_swmr_gaussians + @test -e r_vfd_swmr_gaussians || ln -s vfd_swmr_gaussians r_vfd_swmr_gaussians if BUILD_ALL_CONDITIONAL noinst_PROGRAMS=$(BUILD_ALL_PROGS) diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index 043b7ed..9da0640 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -333,3 +333,22 @@ fetch_env_ulong(const char *varname, unsigned long limit, unsigned long *valp) *valp = ul; return 1; } + +/* + * For demo credel.c: need to write up description + */ +size_t +strlcpy(char *dst, const char *src, size_t size) +{ + char *d; + const char *s; + + for (d = dst, s = src; (s - src) < (int)size; d++, s++) { + *d = *s; + if (*s == '\0') + return (size_t) (s - src); + } + + dst[size - 1] = '\0'; + return size; +} diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index a4bf50e..86f5f45 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -19,6 +19,7 @@ /***********/ #include +#include /* For demo */ #include "h5test.h" /**********/ @@ -35,6 +36,11 @@ /* The message sent by writer that the file open is done--releasing the file lock */ #define VFD_SWMR_WRITER_MESSAGE "VFD_SWMR_WRITER_MESSAGE" +/* For demo */ +#ifndef __arraycount +#define __arraycount(__a) (sizeof(__a) / sizeof((__a)[0])) +#endif + /************/ /* Typedefs */ /************/ @@ -88,6 +94,9 @@ H5TEST_DLL void esnprintf(char *, size_t, const char *, ...) H5TEST_DLL int fetch_env_ulong(const char *, unsigned long, unsigned long *); +/* For demo */ +H5TEST_DLL size_t strlcpy(char *, const char *, size_t); + #ifdef __cplusplus } #endif diff --git a/test/vfd_swmr_credel.c b/test/vfd_swmr_credel.c new file mode 100644 index 0000000..fe6f0d5 --- /dev/null +++ b/test/vfd_swmr_credel.c @@ -0,0 +1,483 @@ +/* + * 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. + */ + +#include +#include +#include +#include /* basename(3) */ +#include +#include +#include +#include +#include /* struct timespec, nanosleep */ +#include /* getopt, PATH_MAX, ... */ + +#include "hdf5.h" +#include "vfd_swmr_common.h" + +#define DATAROWS 1 +#define DATACOLS 10 +static const hsize_t dims[2] = {DATAROWS, DATACOLS}; +static const hsize_t chunk_dims[2] = {1, 1}; +static volatile sig_atomic_t unbroken = 1; + +typedef struct { + uint64_t created, deleted; +} stats_pair_t; + +typedef struct { + stats_pair_t datasets, groups; + uint64_t iterations; +} stats_t; + +typedef struct { + hid_t dataset[4], dataspace, dapl, dcpl, file, group[2]; + char output_file[PATH_MAX]; + char progname[PATH_MAX]; + struct timespec update_interval; + int verbose; + bool oneshot; + bool print_stats; + bool use_vfd_swmr; + uint64_t iterations_limit; + stats_t stats; +} state_t; + +#define ALL_HID_INITIALIZER (state_t){ \ + .dataspace = H5I_INVALID_HID \ + , .file = H5I_INVALID_HID \ + , .verbose = 0 \ + , .oneshot = false \ + , .use_vfd_swmr = true \ + , .print_stats = false \ + , .iterations_limit = UINT64_MAX \ + , .output_file = "" \ + , .update_interval = (struct timespec){ \ + .tv_sec = 0 \ + , .tv_nsec = 1000000000UL / 10 /* 1/10 second */} \ + , .stats = {{0, 0}, {0, 0}}} + +static void state_init(state_t *, int, char **); + +static void +write_dataset(state_t *s, const int64_t didx) +{ + const int ndatasets = __arraycount(s->dataset); + hid_t ds; + int32_t data[DATAROWS][DATACOLS]; + herr_t status; + unsigned int i, j; + + for (i = 0; i < (int)__arraycount(data); i++) { + for (j = 0; j < (int)__arraycount(data[i]); j++) { + int64_t k = (didx + j + i ) % (int64_t)__arraycount(data[i]); + + data[i][j] = (0 <= k && k < 3) ? 1 : 0; + if (s->verbose > 1) + fprintf(stderr, " %" PRId32, data[i][j]); + } + if (s->verbose > 1) + fprintf(stderr, "\n"); + } + + ds = s->dataset[didx % ndatasets]; + status = H5Dwrite(ds, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, + H5P_DEFAULT, data); + + if (status < 0) + errx(EXIT_FAILURE, "H5Dwrite failed"); + + if (H5Dflush(ds) < 0) + errx(EXIT_FAILURE, "H5Dflush failed"); +} + +static void +usage(const char *progname) +{ + fprintf(stderr, "usage: %s [-u milliseconds]\n" + "\n" + "-o: oneshot mode, perform one iteration, wait for a signal, " + "then quit.\n" + "-s: print statistics at end\n" + "-S: disable VFD SWMR mode\n" + "-u ms: milliseconds interval between updates to %s.h5\n" + "-v: verbose mode, mention creation/deletion; -vv: print data\n" + "\n", + progname, progname); + exit(EXIT_FAILURE); +} + +static void +print_stats(stats_t *s) +{ + printf("%10" PRIu64 " groups created\n", s->groups.created); + printf("%10" PRIu64 " groups deleted\n", s->groups.deleted); + printf("%10" PRIu64 " datasets created\n", s->datasets.created); + printf("%10" PRIu64 " datasets deleted\n", s->datasets.deleted); + printf("%10" PRIu64 " iterations\n", s->iterations); +} + +static void +state_init(state_t *s, int argc, char **argv) +{ + int ch, i, rc; + char tfile[PATH_MAX]; + char *end; + unsigned long millis; + uintmax_t niters; + + *s = ALL_HID_INITIALIZER; + strlcpy(tfile, argv[0], sizeof(tfile)); + strlcpy(s->progname, basename(tfile), sizeof(s->progname)); + while ((ch = getopt(argc, argv, "n:ou:sSv")) != -1) { + switch (ch) { + case 'n': + niters = strtoumax(optarg, &end, 0); + if (niters == UINTMAX_MAX && errno == ERANGE) { + err(EXIT_FAILURE, "option -%c argument \"%s\"", + ch, optarg); + } else if (*end != '\0') { + errx(EXIT_FAILURE, + "garbage after -%c argument \"%s\"", ch, + optarg); + } + s->iterations_limit = niters; + break; + case 'o': + s->oneshot = true; + break; + case 's': + s->print_stats = true; + break; + case 'S': + s->use_vfd_swmr = false; + break; + case 'u': + errno = 0; + millis = strtoul(optarg, &end, 0); + if (millis == ULONG_MAX && errno == ERANGE) { + err(EXIT_FAILURE, "option -%c argument \"%s\"", + ch, optarg); + } else if (*end != '\0') { + errx(EXIT_FAILURE, + "garbage after -%c argument \"%s\"", ch, + optarg); + } + s->update_interval.tv_sec = (time_t)(millis / 1000UL); + s->update_interval.tv_nsec = (long)((millis * 1000000UL) % 1000000000UL); + warnx("%lu milliseconds between updates", millis); + break; + case 'v': + s->verbose++; + break; + case '?': + default: + usage(s->progname); + } + } + argc -= optind; + argv += optind; + + for (i = 0; i < (int)__arraycount(s->dataset); i++) + s->dataset[i] = H5I_INVALID_HID; + + for (i = 0; i < (int)__arraycount(s->group); i++) + s->group[i] = H5I_INVALID_HID; + + rc = snprintf(s->output_file, sizeof(s->output_file), "%s.h5", s->progname); + if (rc == -1 || rc >= (int)sizeof(s->output_file)) + errx(EXIT_FAILURE, "output filename was truncated"); +} + +static void +delete_group(state_t *s, const int64_t gidx) +{ + hid_t g; + const int ngroups = __arraycount(s->group); + char gname[32]; + + assert(0 <= gidx); + + snprintf(gname, sizeof(gname), "/group-%" PRId64, gidx); + g = s->group[gidx % ngroups]; + + if (H5Ldelete(s->file, gname, H5P_DEFAULT) < 0) { + errx(EXIT_FAILURE, "%s: H5Ldelete(, \"%s\", ) failed", + __func__, gname); + } + + if (H5Gclose(g) < 0) + errx(EXIT_FAILURE, "H5Gclose failed"); + + if (s->verbose > 0) + fprintf(stderr, "Deleted group %s\n", gname); + + s->group[gidx % ngroups] = H5I_INVALID_HID; + s->stats.groups.deleted++; +} + +static void +create_group(state_t *s, const int64_t gidx) +{ + const int ngroups = __arraycount(s->group); + hid_t g; + char gname[32]; + + assert(0 <= gidx); + assert(s->group[gidx % ngroups] == H5I_INVALID_HID); + + snprintf(gname, sizeof(gname), "/group-%" PRId64, gidx); + g = H5Gcreate(s->file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (g < 0) + errx(EXIT_FAILURE, "H5Gcreate failed"); + + if (s->verbose > 0) + fprintf(stderr, "Created group %s\n", gname); + s->group[gidx % ngroups] = g; + s->stats.groups.created++; +} + +static void +delete_dataset(state_t *s, const int64_t didx) +{ + const int ndatasets = __arraycount(s->dataset); + const hid_t ds = s->dataset[didx % ndatasets]; + char dname[32]; + const int64_t gidx = didx / 2; + + assert(0 <= gidx && 0 <= didx); + + snprintf(dname, sizeof(dname), "/group-%" PRId64 "/dataset-%" PRId64, + gidx, didx); + if (H5Ldelete(s->file, dname, H5P_DEFAULT) < 0) { + errx(EXIT_FAILURE, "%s: H5Ldelete(, \"%s\", ) failed", + __func__, dname); + } + + if (s->verbose > 0) + fprintf(stderr, "Deleted dataset %s\n", dname); +#if 1 + if (H5Dclose(ds) < 0) + errx(EXIT_FAILURE, "H5Dclose failed"); +#endif + s->dataset[didx % ndatasets] = H5I_INVALID_HID; + s->stats.datasets.deleted++; +} + +static void +create_dataset(state_t *s, const int64_t didx) +{ + const int ndatasets = __arraycount(s->dataset); + char dname[32]; + const int64_t gidx = didx / 2; + hid_t ds; + + assert(0 <= gidx && 0 <= didx); + assert(s->dataset[didx % ndatasets] == H5I_INVALID_HID); + + s->dataspace = H5Screate_simple(__arraycount(dims), dims, NULL); + + if (s->dataspace < 0) + errx(EXIT_FAILURE, "H5Screate_simple failed"); + + snprintf(dname, sizeof(dname), "/group-%" PRId64 "/dataset-%" PRId64, + gidx, didx); + ds = H5Dcreate2(s->file, dname, + H5T_STD_I32BE, s->dataspace, + H5P_DEFAULT, s->dcpl, s->dapl); + + if (H5Sclose(s->dataspace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); + + s->dataspace = H5I_INVALID_HID; + + if (ds < 0) + errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); + + if (s->verbose > 0) + fprintf(stderr, "Created dataset %s\n", dname); + s->dataset[didx % ndatasets] = ds; + s->stats.datasets.created++; +} + +static void +create_and_write_dataset(state_t *s, const int64_t didx) +{ +#if 0 + const int64_t gidx = didx / 2; + const int ngroups = __arraycount(s->group); + const hid_t g = s->group[gidx % ngroups]; + + if (H5Odisable_mdc_flushes(g) < 0) + err(EXIT_FAILURE, "H5Odisable_mdc_flushes failed"); +#endif + + create_dataset(s, didx); + write_dataset(s, didx); + +#if 0 + if (H5Oenable_mdc_flushes(g) < 0) + err(EXIT_FAILURE, "H5Oenable_mdc_flushes failed"); +#endif +} + +static void +handle_signal(int H5_ATTR_UNUSED signo) +{ + char msg[] = "Handling signal\n"; + write(STDERR_FILENO, msg, sizeof(msg) - 1); + unbroken = 0; +} + +static void +disestablish_handler(const struct sigaction *osa) +{ + if (sigaction(SIGINT, osa, NULL) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +static void +establish_handler(struct sigaction *osa) +{ + struct sigaction sa; + + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = handle_signal; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, osa) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +int +main(int argc, char **argv) +{ + hid_t fapl, fcpl; + struct sigaction osa; + state_t storage; + state_t *s = &storage; + int64_t i; + H5F_vfd_swmr_config_t config; + + memset(&config, '\0', sizeof(config)); + + state_init(s, argc, argv); + + /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ + init_vfd_swmr_config(&config, 4, 5, true, FALSE, 128, "./my_md_file"); + + /* use_latest_format, use_vfd_swmr, only_meta_page, config */ + fapl = vfd_swmr_create_fapl(false, s->use_vfd_swmr, true, &config); + if (fapl < 0) { + errx(EXIT_FAILURE, "%s.%d vfd_swmr_create_fapl failed", + __func__, __LINE__); + } + + fcpl = H5Pcreate(H5P_FILE_CREATE); + if (fcpl < 0) { + errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", + __func__, __LINE__); + } + + /* Set file space strategy to paged aggregation in fcpl. + * Page buffering *requires* this strategy. + * + * I set the free-space threshold to 1GB so that deleted + * datasets are not recycled. + */ + if (H5Pset_file_space_strategy(fcpl, + H5F_FSPACE_STRATEGY_PAGE, false, 1024 * 1024 * 1024) < 0) + errx(EXIT_FAILURE, "H5Pset_file_space_strategy failed"); + + s->file = H5Fcreate(s->output_file, H5F_ACC_TRUNC, fcpl, fapl); + + H5Pclose(fapl); + + if (s->file < 0) + errx(EXIT_FAILURE, "H5Fcreate failed"); + + if ((s->dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", + __func__, __LINE__); + } + if ((s->dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", + __func__, __LINE__); + } + if (H5Pset_chunk(s->dcpl, 2, chunk_dims) < 0) + errx(EXIT_FAILURE, "H5Pset_chunk failed"); + if (H5Pset_chunk_cache(s->dapl, H5D_CHUNK_CACHE_NSLOTS_DEFAULT, 0, + H5D_CHUNK_CACHE_W0_DEFAULT) < 0) + errx(EXIT_FAILURE, "H5Pset_chunk_cache failed"); + + establish_handler(&osa); + + for (i = 0; i < 4; i++) { + s->stats.iterations++; + if (i % 2 == 0) + create_group(s, i / 2); + create_and_write_dataset(s, i); + } + + for (i = 5; unbroken; i += 2) { + delete_dataset(s, i - 5); + delete_dataset(s, i - 4); + delete_group(s, (i - 4) / 2); + create_group(s, i / 2); + create_and_write_dataset(s, i - 1); + create_and_write_dataset(s, i); + if (s->oneshot || ++s->stats.iterations >= s->iterations_limit) + break; + nanosleep(&s->update_interval, NULL); + } + + if (s->oneshot) { + sigset_t mask; + sigemptyset(&mask); + H5Fvfd_swmr_end_tick(s->file); + (void)sigsuspend(&mask); + } +#if 0 + fprintf(stderr, "Interrupted. Cleaning up.\n"); + + int j; + for (--i, j = 0; j < 4; j++, --i) { + if (i % 2 == 1) { + delete_dataset(s, i - 1); + delete_dataset(s, i); + delete_group(s, i / 2); + } + } + + for (j = 0; j < 4; j++) { + assert(s->dataset[j] == H5I_INVALID_HID); + assert(s->group[j / 2] == H5I_INVALID_HID); + } +#endif + + if (s->print_stats) + print_stats(&s->stats); + + if (H5Fclose(s->file) < 0) + errx(EXIT_FAILURE, "H5Fclose failed"); + + if (H5Pclose(s->dapl) < 0) + errx(EXIT_FAILURE, "H5Pclose failed"); + + if (H5Pclose(s->dcpl) < 0) + errx(EXIT_FAILURE, "H5Pclose failed"); + + disestablish_handler(&osa); + + return EXIT_SUCCESS; +} diff --git a/test/vfd_swmr_gaussians.c b/test/vfd_swmr_gaussians.c new file mode 100644 index 0000000..17231a9 --- /dev/null +++ b/test/vfd_swmr_gaussians.c @@ -0,0 +1,753 @@ +#include +#include +#include +#include +#include /* basename(3) */ +#include /* expf(3) */ +#include /* setlocale(3) */ +#include +#include +#include +#include +#include /* struct timespec, nanosleep(2), time(3), + * clock_gettime(2) + */ +#include /* getopt, PATH_MAX, ... */ + +#include /* for MIN(a, b) */ + +#include "hdf5.h" +#include "vfd_swmr_common.h" +#include "H5time_private.h" + +#define SWMR_TICK_LEN 4 /* in 100 ms */ + +typedef enum { + STANDALONE = 0 + , READ = 1 + , WRITE = 2 +} personality_t; + +typedef enum { + TOP = 0 + , BOTTOM + , LEFT + , RIGHT + , NSIDES +} side_t; + +typedef struct { + bool side[NSIDES]; +} inside_t; + +typedef struct { + float x, y; +} vec_t; + +#define RANK 3 +#define ROWS 20 +#define COLS 40 +static const hsize_t original_dims[RANK] = {0, ROWS, COLS}; +static const hsize_t max_dims[RANK] = {H5S_UNLIMITED, ROWS, COLS}; +static const hsize_t frame_dims[RANK] = {1, ROWS, COLS}; +static const hsize_t *chunk_dims = frame_dims; +static volatile sig_atomic_t unbroken = 1; + +typedef struct { + /* main-loop statistics */ + uint64_t max_elapsed_ns, min_elapsed_ns, total_elapsed_ns; + uint64_t total_loops; + hid_t dataset, memspace, dcpl, file, group; + char output_file[PATH_MAX]; + char progname[PATH_MAX]; + struct timespec update_interval; + bool fuzz; + bool constantrate; + unsigned int partstep; +} state_t; + +#define ALL_HID_INITIALIZER (state_t){ \ + .total_elapsed_ns = 0 \ + , .total_loops = 0 \ + , .min_elapsed_ns = UINT64_MAX \ + , .max_elapsed_ns = 0 \ + , .memspace = H5I_INVALID_HID \ + , .file = H5I_INVALID_HID \ + , .constantrate = false \ + , .partstep = 0 \ + , .output_file = "" \ + , .update_interval = (struct timespec){ \ + .tv_sec = 0 \ + , .tv_nsec = 1000000000UL / 30 /* 1/30 second */}} + +static void state_init(state_t *, int, char **); + +static void +usage(const char *progname) +{ + fprintf(stderr, "usage: %s [-u milliseconds]\n" + "\n" + "-c: increase the frame number continously (reader mode)\n" + "-f: add \"fuzz\" (linear noise) to the data (writer mode)\n" + "-u ms: milliseconds interval between updates to %s.h5\n" + "\n", + progname, progname); + exit(EXIT_FAILURE); +} + +static void +state_init(state_t *s, int argc, char **argv) +{ + int ch; + char tfile[PATH_MAX]; + char *end; + unsigned long millis; + int nprinted; + + *s = ALL_HID_INITIALIZER; + strlcpy(tfile, argv[0], sizeof(tfile)); + strlcpy(s->progname, basename(tfile), sizeof(s->progname)); + + while ((ch = getopt(argc, argv, "cfu:")) != -1) { + switch (ch) { + case 'c': + s->constantrate = true; + break; + case 'f': + s->fuzz = true; + 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); + + warnx("%lu milliseconds between updates", millis); + break; + case '?': + default: + usage(s->progname); + } + } + argc -= optind; + argv += optind; + + s->dataset = H5I_INVALID_HID; + s->group = H5I_INVALID_HID; + + s->memspace = H5Screate_simple(RANK, frame_dims, NULL); + + if (s->memspace < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", + __func__, __LINE__); + } + + nprinted = snprintf(s->output_file, sizeof(s->output_file), + "%s.h5", s->progname); + if (nprinted < 0 || nprinted >= (int)sizeof(s->output_file)) { + errx(EXIT_FAILURE, "%s.%d: output filename truncated.", + __func__, __LINE__); + } +} + +static void +matrix_read(state_t *s, int *framenop, float mat[ROWS][COLS]) +{ + hid_t ds, filespace; + herr_t status; + hsize_t dims[RANK]; + int lead; + hssize_t temp; + + const uint64_t update_ms = timespec2ns(&s->update_interval) / 1000000; + const uint32_t tick_ms = SWMR_TICK_LEN * 100; + const uint64_t updates_per_tick = (tick_ms + update_ms - 1) / update_ms; + const uint64_t tmp = 2 * updates_per_tick; + const hssize_t hang_back = (hssize_t)tmp; + const int frameno = *framenop; + hsize_t offset[RANK] = {(hsize_t)frameno, 0, 0}; + + ds = s->dataset; + + if (H5Drefresh(ds) < 0) + errx(EXIT_FAILURE, "H5Drefresh failed"); + + filespace = H5Dget_space(ds); + + if (H5Sget_simple_extent_dims(filespace, dims, NULL) < 0) + errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); + + if (dims[1] != original_dims[1] || dims[2] != original_dims[2]) { + errx(EXIT_FAILURE, "Unexpected dimensions N x %ju x %ju", + (uintmax_t)dims[1], (uintmax_t)dims[2]); + } + + + temp = frameno + hang_back - (hssize_t)dims[0]; + lead = (int)temp; + + if (s->constantrate) { + *framenop = frameno + 1; + } else if (lead > hang_back * 2) { + if (++s->partstep % 3 == 0) + *framenop = frameno + 1; + } else if (lead > 0) { + if (++s->partstep % 2 == 0) + *framenop = frameno + 1; + } else if (lead == 0) { + *framenop = frameno + 1; + } else if (lead < -hang_back * 2) { + /* We're way behind, so jump close to the front. */ + temp = (hssize_t)dims[0] - hang_back; + *framenop = (int)temp; + } else /* lead < 0 */ { + *framenop = frameno + 1; + if (++s->partstep % 2 == 0) + *framenop = frameno + 2; + } + +#if 0 + if (!s->constantrate && (lead < -2 || 2 < lead)) { + int gain = 31250 / 4; + const struct timespec prior_integral = s->update_integral; + struct timespec current_interval; + if (lead > 0) + gain *= 2; + struct timespec adjustment = (struct timespec){.tv_sec = 0, + .tv_nsec = gain * MAX(MIN(4, lead), -4)}; + /* XXX clamp it XXX */ + timespecadd(&s->update_integral, + &adjustment, &s->update_integral); + timespecadd(&s->update_integral, + &s->update_interval, ¤t_interval); + if (timespeccmp(¤t_interval, &s->min_interval, <=)) + s->update_integral = prior_integral; + } +#endif + + if (frameno >= (int)dims[0]) { + int i, j; + for (i = 0; i < ROWS; i++) { + for (j = 0; j < COLS; j++) + mat[i][j] = ((i + j) % 2 == 0) ? 0. : 1.; + } + return; + } + + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, + frame_dims, NULL) < 0) + errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); + + status = H5Dread(ds, H5T_NATIVE_FLOAT, s->memspace, filespace, + H5P_DEFAULT, mat); + + if (status < 0) + errx(EXIT_FAILURE, "H5Dread failed"); + + if (H5Sclose(filespace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); +} + +static void +matrix_write(state_t *s, int frameno, float mat[ROWS][COLS]) +{ + hid_t ds, filespace; + herr_t status; + hsize_t size[RANK] = {(hsize_t)frameno + 1, ROWS, COLS}; + hsize_t offset[RANK] = {(hsize_t)frameno, 0, 0}; + + ds = s->dataset; + + if (H5Dset_extent(ds, size) < 0) + errx(EXIT_FAILURE, "H5Dset_extent failed"); + + filespace = H5Dget_space(ds); + + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, + frame_dims, NULL) < 0) + errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); + + status = H5Dwrite(ds, H5T_NATIVE_FLOAT, s->memspace, filespace, + H5P_DEFAULT, mat); + + if (status < 0) + errx(EXIT_FAILURE, "H5Dwrite failed"); + + if (H5Sclose(filespace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); + + if (H5Dflush(ds) < 0) + errx(EXIT_FAILURE, "H5Dflush failed"); +} + +static void +open_group(state_t *s) +{ + hid_t g; + const char *gname = "/group-0"; + + assert(s->group == H5I_INVALID_HID); + + g = H5Gopen(s->file, gname, H5P_DEFAULT); + + if (g < 0) + errx(EXIT_FAILURE, "H5Gcreate failed"); + + fprintf(stderr, "Opened group %s\n", gname); + s->group = g; +} + +static void +create_group(state_t *s) +{ + hid_t g; + const char *gname = "/group-0"; + + assert(s->group == H5I_INVALID_HID); + + g = H5Gcreate(s->file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (g < 0) + errx(EXIT_FAILURE, "H5Gcreate failed"); + + s->group = g; +} + +static void +open_dataset(state_t *s) +{ + const char *dname = "/group-0/dataset-0"; + hid_t ds; + hid_t filespace; + hid_t ty; + hsize_t dims[RANK], maxdims[RANK]; + + assert(s->dataset == H5I_INVALID_HID); + + ds = H5Dopen(s->file, dname, H5P_DEFAULT); + + if (ds < 0) + errx(EXIT_FAILURE, "H5Dopen(, \"%s\", ) failed", dname); + + if ((ty = H5Dget_type(ds)) < 0) + errx(EXIT_FAILURE, "H5Dget_type failed"); + + if (H5Tequal(ty, H5T_IEEE_F32BE) <= 0) + errx(EXIT_FAILURE, "Unexpected data type"); + + if ((filespace = H5Dget_space(ds)) < 0) + errx(EXIT_FAILURE, "H5Dget_space failed"); + + if (H5Sget_simple_extent_ndims(filespace) != RANK) + errx(EXIT_FAILURE, "Unexpected rank"); + + if (H5Sget_simple_extent_dims(filespace, dims, maxdims) < 0) + errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); + + if (dims[1] != original_dims[1] || dims[2] != original_dims[2]) { + errx(EXIT_FAILURE, "Unexpected dimensions ? x %ju x %ju", + (uintmax_t)dims[1], (uintmax_t)dims[2]); + } + + if (maxdims[1] != original_dims[1] || maxdims[2] != original_dims[2]) { + errx(EXIT_FAILURE, + "Unexpected maximum dimensions ? x %ju x %ju", + (uintmax_t)dims[1], (uintmax_t)dims[2]); + } + + fprintf(stderr, "Opened dataset %s\n", dname); + s->dataset = ds; +} + +static void +create_dataset(state_t *s) +{ + const char *dname = "/group-0/dataset-0"; + hid_t ds; + hid_t filespace; + + assert(s->dataset == H5I_INVALID_HID); + + filespace = H5Screate_simple(__arraycount(original_dims), original_dims, + max_dims); + + if (filespace < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", + __func__, __LINE__); + } + + if ((s->dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", + __func__, __LINE__); + } + + if (H5Pset_chunk(s->dcpl, RANK, chunk_dims) < 0) + errx(EXIT_FAILURE, "H5Pset_chunk failed"); + + ds = H5Dcreate2(s->file, dname, H5T_IEEE_F32BE, filespace, + H5P_DEFAULT, s->dcpl, H5P_DEFAULT); + + if (H5Sclose(filespace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); + + filespace = H5I_INVALID_HID; + + if (ds < 0) + errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); + + s->dataset = ds; +} + +static void +handle_signal(int H5_ATTR_UNUSED signo) +{ + unbroken = 0; +} + +static void +disestablish_handler(const struct sigaction *osa) +{ + if (sigaction(SIGINT, osa, NULL) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +static void +establish_handler(struct sigaction *osa) +{ + struct sigaction sa; + + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = handle_signal; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, osa) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +static void +step(vec_t *center, vec_t *direction, float steplen, bool *recursed) +{ + static const float top = 0., bottom = (float)COLS, + left = 0., right = (float)ROWS; + struct { + bool top, bottom, left, right; + } bounce = {false, false, false, false}; + float xback, yback; + vec_t before = *center; + vec_t after = (vec_t){.x = before.x + direction->x * steplen, + .y = before.y + direction->y * steplen}; + + if (before.x < right && after.x >= right) { + xback = (right - before.x) / (after.x - before.x); + bounce.right = true; + } else if (before.x > left && after.x <= left) { + xback = (before.x - left) / (before.x - after.x); + bounce.left = true; + } else + xback = 0.; + + if (before.y < bottom && after.y >= bottom) { + yback = (bottom - before.y) / (after.y - before.y); + bounce.bottom = true; + } else if (before.y > top && after.y <= top) { + yback = (before.y - top) / (before.y - after.y); + bounce.top = true; + } else + yback = 0.; + + /* I shorten the step length until a corner crossing becomes + * a side crossing. + */ + if ((bounce.top && bounce.right) || + (bounce.right && bounce.bottom) || + (bounce.bottom && bounce.left) || + (bounce.left && bounce.top)) { + + float newsteplen = steplen * 2 / 3; + if (recursed != NULL) + *recursed = true; + step(center, direction, newsteplen, NULL); + step(center, direction, steplen - newsteplen, NULL); + } + if (bounce.right || bounce.left) { + after.x = before.x + direction->x * (2 * xback - 1) * steplen; + direction->x = -direction->x; + } + if (bounce.top || bounce.bottom) { + after.y = before.y + direction->y * (2 * yback - 1) * steplen; + direction->y = -direction->y; + } + *center = after; +} + +static float +gaussian(float x, float y, float r) +{ + return expf(-(x * x + y * y) / (r * r)); +} + +static int +stepno(float v) +{ + if ((double)v < 1. / 8.) + return 0; + if ((double)v < 3. / 8.) + return 1; + if ((double)v < 7 / 8.) + return 2; + + return 3; +} + +static void +draw_border(WINDOW *w) +{ + wborder(w, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static void +matrix_draw(WINDOW *w, float mat[ROWS][COLS]) +{ + int ch, i, j; + static char steps[] = " .oO"; + + wclear(w); + draw_border(w); + for (i = 0; i < ROWS; i++) { + wmove(w, 1 + i, 1); + for (j = 0; j < COLS; j++) { + ch = steps[stepno(mat[i][j])]; + waddch(w, (const chtype)ch); + } + } + + wnoutrefresh(w); +} + +static void +matrix_compute(vec_t *center, size_t ncenters, float mat[ROWS][COLS]) +{ + int i, j, k; + float radius = 4; + + for (i = 0; i < ROWS; i++) { + for (j = 0; j < COLS; j++) { + mat[i][j] = 0.; + for (k = 0; k < (int)ncenters; k++) { + mat[i][j] += gaussian((float)i - center[k].x, + (float)j - center[k].y, radius); + } + } + } +} + +static void +move_centers(vec_t *center, vec_t *direction, size_t ncenters) +{ + const float steplen = (float).01; + int k; + bool recursed[2] = {false, false}; + + for (k = 0; k < (int)ncenters; k++) { + recursed[k] = false; + step(¢er[k], &direction[k], steplen, &recursed[k]); + } +} + +static void +matrix_open(state_t *s, bool rw) +{ + const char *func; + hid_t fapl, fcpl; + H5F_vfd_swmr_config_t config; + + memset(&config, '\0', sizeof(config)); + + /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ + init_vfd_swmr_config(&config, SWMR_TICK_LEN, 5, rw, FALSE, 128, "./my_md_file"); + + /* use_latest_format, use_vfd_swmr, only_meta_page, config */ + fapl = vfd_swmr_create_fapl(false, true, true, &config); + if (fapl < 0) { + errx(EXIT_FAILURE, "%s.%d vfd_swmr_create_fapl failed", + __func__, __LINE__); + } + + fcpl = H5Pcreate(H5P_FILE_CREATE); + if (fcpl < 0) { + errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", + __func__, __LINE__); + } + + /* Set file space strategy to paged aggregation in fcpl. + * Page buffering *requires* this strategy. + * + * I set the free-space threshold to 1GB so that deleted + * datasets are not recycled. + */ + if (H5Pset_file_space_strategy(fcpl, + H5F_FSPACE_STRATEGY_PAGE, false, 1024 * 1024 * 1024) < 0) + errx(EXIT_FAILURE, "H5Pset_file_space_strategy failed"); + + if (rw) { + s->file = H5Fcreate("vfd_swmr_gaussians.h5", H5F_ACC_TRUNC, fcpl, fapl); + func = "H5Fcreate"; + } else { + s->file = H5Fopen("vfd_swmr_gaussians.h5", H5F_ACC_RDONLY, fapl); + func = "H5Fopen"; + } + + H5Pclose(fapl); + + if (s->file < 0) + errx(EXIT_FAILURE, "%s failed", func); +} + +static void +fuzz(float mat[ROWS][COLS]) +{ + int i, j; + + for (i = 0; i < ROWS; i++) { + for (j = 0; j < COLS; j++) { + long int temp = random() / RAND_MAX * (long int)(9. / 64.); + mat[i][j] += (float)temp; + } + } +} + +int +main(int argc, char **argv) +{ + char buf[32]; + float mat[ROWS][COLS]; + int frameno; + vec_t center[2] = {{.x = .5, .y = .5}, + {.x = ROWS - .5, .y = COLS - .5}}; + vec_t direction[2] = {{.x = 3, .y = 7}, {.x = 43, .y = 41}}; + struct sigaction osa; + WINDOW *topw = NULL, *w = NULL; + personality_t personality; + state_t s; + uint64_t temp; + + srandom((unsigned int)time(NULL)); + + setlocale(LC_ALL, ""); + + state_init(&s, argc, argv); + + switch (s.progname[0]) { + case 'r': + personality = READ; + break; + case 'w': + personality = WRITE; + break; + default: + personality = STANDALONE; + break; + } + establish_handler(&osa); + + switch (personality) { + case WRITE: + matrix_open(&s, true); + create_group(&s); + create_dataset(&s); + break; + case READ: + matrix_open(&s, false); + open_group(&s); + open_dataset(&s); + break; + default: + break; + } + + if ((topw = initscr()) == NULL) + errx(EXIT_FAILURE, "initscr failed"); + else if ((w = subwin(topw, ROWS + 2, COLS + 2, 0, 0)) == NULL) + errx(EXIT_FAILURE, "subwin failed"); + + for (frameno = 0; unbroken; ) { + struct timespec elapsed, start, stop; + uint64_t elapsed_ns; + clock_gettime(CLOCK_MONOTONIC, &start); + + switch (personality) { + case READ: + matrix_read(&s, &frameno, mat); + break; + case WRITE: + case STANDALONE: + matrix_compute(center, __arraycount(center), mat); + if (s.fuzz) + fuzz(mat); + break; + } + switch (personality) { + case READ: + case STANDALONE: + matrix_draw(w, mat); +#if 0 + wmove(topw, ROWS + 3, 0); + waddstr(topw, "\"Don't cross the streams.\""); +#endif + break; + case WRITE: + matrix_write(&s, frameno, mat); + break; + } + + snprintf(buf, sizeof(buf), "Frame %d.", frameno); + wmove(topw, ROWS + 2, 0); + waddstr(topw, buf); + snprintf(buf, sizeof(buf), "Rate %lld/s.", + 1000000000ULL / timespec2ns(&s.update_interval)); + wmove(topw, ROWS + 2, COLS + 2 - (int)strlen(buf)); + waddstr(topw, buf); + wnoutrefresh(topw); + doupdate(); + + nanosleep(&s.update_interval, NULL); + + switch (personality) { + case STANDALONE: + case WRITE: + move_centers(center, direction, __arraycount(center)); + frameno++; + break; + case READ: + break; + } + clock_gettime(CLOCK_MONOTONIC, &stop); + + timespecsub(&stop, &start, &elapsed); + elapsed_ns = timespec2ns(&elapsed); + + if (elapsed_ns < s.min_elapsed_ns) + s.min_elapsed_ns = elapsed_ns; + if (elapsed_ns > s.max_elapsed_ns) + s.max_elapsed_ns = elapsed_ns; + s.total_elapsed_ns += elapsed_ns; + s.total_loops++; + } + endwin(); + fprintf(stderr, "Iteration stats:\n"); + fprintf(stderr, "min. elapsed %" PRIu64 " ms\n", + s.min_elapsed_ns / 1000000); + fprintf(stderr, "max. elapsed %" PRIu64 " ms\n", + s.max_elapsed_ns / 1000000); + temp = s.total_elapsed_ns / s.total_loops / 1000000; + fprintf(stderr, "avg. elapsed %.3f ms\n", (double)temp); + disestablish_handler(&osa); + return EXIT_SUCCESS; +} -- cgit v0.12 From 77f2b0b2071b976a42c41fbddad28ed7823675c2 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 12:45:20 -0800 Subject: Fixes leading underscores in VFD SWMR include guards --- src/H5FDvfd_swmr.h | 3 +-- src/H5FDvfd_swmr_private.h | 6 +++--- src/H5queue.h | 6 +++--- src/hlog.h | 6 +++--- test/vfd_swmr_common.h | 6 +++--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/H5FDvfd_swmr.h b/src/H5FDvfd_swmr.h index 86e9d0f..fd5c0bd 100644 --- a/src/H5FDvfd_swmr.h +++ b/src/H5FDvfd_swmr.h @@ -34,5 +34,4 @@ H5_DLL herr_t H5Pset_fapl_vfd_swmr(hid_t fapl_id); } #endif -#endif - +#endif /* H5FDswmr_H */ diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 74a937f..d79ec94 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -9,8 +9,8 @@ * help@hdfgroup.org. */ -#ifndef _H5FDvfd_swmr_private_H -#define _H5FDvfd_swmr_private_H +#ifndef H5FDvfd_swmr_private_H +#define H5FDvfd_swmr_private_H #include "H5queue.h" /* for TAILQ_* */ #include "hlog.h" /* for TAILQ_* */ @@ -90,4 +90,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 */ +#endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5queue.h b/src/H5queue.h index a84ba52..bef7ef7 100644 --- a/src/H5queue.h +++ b/src/H5queue.h @@ -31,8 +31,8 @@ * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ -#ifndef _H5queue_H_ -#define _H5queue_H_ +#ifndef H5queue_H_ +#define H5queue_H_ /* This is a copy of netBSD's sys/queue.h header for use in HDF5. We've copied * it here instead of using the system's version to avoid incompatibilities. @@ -679,4 +679,4 @@ struct { \ ((struct type *)(void *) \ ((char *)((head)->sqh_last) - offsetof(struct type, field)))) -#endif /* _H5queue_H_ */ +#endif /* H5queue_H_ */ diff --git a/src/hlog.h b/src/hlog.h index 2489a47..6a91674 100644 --- a/src/hlog.h +++ b/src/hlog.h @@ -9,8 +9,8 @@ * * See COPYING at the top of the HDF5 distribution for license terms. */ -#ifndef _HLOG_H -#define _HLOG_H +#ifndef HLOG_H +#define HLOG_H #include #include @@ -135,4 +135,4 @@ void hlog_always(struct hlog_outlet *, const char *, ...) void hlog_impl(struct hlog_outlet *, const char *, ...) _printflike(2,3); -#endif /* _HLOG_H */ +#endif /* HLOG_H */ diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index a4bf50e..f64ee87 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -11,8 +11,8 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef _VFD_SWMR_COMMON_H -#define _VFD_SWMR_COMMON_H +#ifndef VFD_SWMR_COMMON_H +#define VFD_SWMR_COMMON_H /***********/ /* Headers */ @@ -94,4 +94,4 @@ H5TEST_DLL int fetch_env_ulong(const char *, unsigned long, unsigned long *); extern int verbosity; -#endif /* _SWMR_COMMON_H */ +#endif /* SWMR_COMMON_H */ -- cgit v0.12 From 051cf5330ba06f113de88de22c201f00677cbdc3 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 12:47:53 -0800 Subject: Minor change to H5FDvfd_swmr.h include guard name --- src/H5FDvfd_swmr.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/H5FDvfd_swmr.h b/src/H5FDvfd_swmr.h index fd5c0bd..7d3b966 100644 --- a/src/H5FDvfd_swmr.h +++ b/src/H5FDvfd_swmr.h @@ -14,8 +14,8 @@ /* * The public header file for the VFD SWMR driver. */ -#ifndef H5FDswmr_H -#define H5FDswmr_H +#ifndef H5FDvfd_swmr_H +#define H5FDvfd_swmr_H #include "H5api_adpt.h" /* H5_DLL */ #include "H5public.h" /* uint64_t *ahem* */ @@ -34,4 +34,4 @@ H5_DLL herr_t H5Pset_fapl_vfd_swmr(hid_t fapl_id); } #endif -#endif /* H5FDswmr_H */ +#endif /* H5FDvfd_swmr_H */ -- cgit v0.12 From d7b277a22aa72f3badcc331e3007df8892e83a80 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 13:54:27 -0800 Subject: Improves autotools and CMake support for sigtimedwait alternative --- CMakeLists.txt | 5 +++++ config/cmake/H5pubconf.h.in | 3 +++ config/cmake_ext_mod/ConfigureChecks.cmake | 1 + configure.ac | 2 +- test/CMakeLists.txt | 8 ++++++++ test/vfd_swmr_common.c | 16 +++++++++------- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac291fa..b6e0044 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -816,8 +816,13 @@ if (HDF5_ENABLE_THREADSAFE) if (Threads_FOUND) set (H5_HAVE_THREADSAFE 1) endif () +else() + # Always check for pthreads for VFD SWMR (for now) + set (THREADS_PREFER_PTHREAD_FLAG ON) + find_package (Threads REQUIRED) endif () + #----------------------------------------------------------------------------- # Option to build the map API #----------------------------------------------------------------------------- diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 64b4852..5f34599 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -352,6 +352,9 @@ /* Define to 1 if you have the `sigsetjmp' function. */ #cmakedefine H5_HAVE_SIGSETJMP @H5_HAVE_SIGSETJMP@ +/* Define to 1 if you have the `sigtimedwait' function. */ +#cmakedefine H5_HAVE_SIGTIMEDWAIT @H5_HAVE_SIGTIMEDWAIT@ + /* Define to 1 if you have the `snprintf' function. */ #cmakedefine H5_HAVE_SNPRINTF @H5_HAVE_SNPRINTF@ diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake index 0ddb6d0..bfa63ac 100644 --- a/config/cmake_ext_mod/ConfigureChecks.cmake +++ b/config/cmake_ext_mod/ConfigureChecks.cmake @@ -518,6 +518,7 @@ CHECK_FUNCTION_EXISTS (setjmp ${HDF_PREFIX}_HAVE_SETJMP) CHECK_FUNCTION_EXISTS (siglongjmp ${HDF_PREFIX}_HAVE_SIGLONGJMP) CHECK_FUNCTION_EXISTS (sigsetjmp ${HDF_PREFIX}_HAVE_SIGSETJMP) CHECK_FUNCTION_EXISTS (sigprocmask ${HDF_PREFIX}_HAVE_SIGPROCMASK) +CHECK_FUNCTION_EXISTS (sigtimedwait ${HDF_PREFIX}_HAVE_SIGTIMEDWAIT) CHECK_FUNCTION_EXISTS (snprintf ${HDF_PREFIX}_HAVE_SNPRINTF) CHECK_FUNCTION_EXISTS (srandom ${HDF_PREFIX}_HAVE_SRANDOM) diff --git a/configure.ac b/configure.ac index 2307b4a..a641a45 100644 --- a/configure.ac +++ b/configure.ac @@ -1958,7 +1958,7 @@ AC_CHECK_FUNCS([alarm clock_gettime difftime fcntl flock fork frexpf]) AC_CHECK_FUNCS([frexpl gethostname getrusage gettimeofday]) AC_CHECK_FUNCS([lstat rand_r random setsysinfo]) AC_CHECK_FUNCS([signal longjmp setjmp siglongjmp sigsetjmp sigprocmask]) -AC_CHECK_FUNCS([snprintf srandom strdup symlink system]) +AC_CHECK_FUNCS([sigtimedwait snprintf srandom strdup symlink system]) AC_CHECK_FUNCS([strtoll strtoull]) AC_CHECK_FUNCS([tmpfile asprintf vasprintf vsnprintf waitpid]) AC_CHECK_FUNCS([roundf lroundf llroundf round lround llround]) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 023c07e..ad6b258 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -46,6 +46,11 @@ if (NOT ONLY_SHARED_LIBS) endif () H5_SET_LIB_OPTIONS (${HDF5_TEST_LIB_TARGET} ${HDF5_TEST_LIB_NAME} STATIC 0) set_target_properties (${HDF5_TEST_LIB_TARGET} PROPERTIES FOLDER libraries/test) + + # Always link to pthreads for VFD SWMR tests + if (NOT WIN32) + target_link_libraries (${HDF5_TEST_LIB_TARGET} PRIVATE Threads::Threads) + endif () endif () if (BUILD_SHARED_LIBS) @@ -66,6 +71,9 @@ if (BUILD_SHARED_LIBS) endif () H5_SET_LIB_OPTIONS (${HDF5_TEST_LIBSH_TARGET} ${HDF5_TEST_LIB_NAME} SHARED "LIB") set_target_properties (${HDF5_TEST_LIBSH_TARGET} PROPERTIES FOLDER libraries/test) + + # Always link to pthreads for VFD SWMR tests + target_link_libraries (${HDF5_TEST_LIBSH_TARGET} PRIVATE Threads::Threads) endif () ################################################################################# diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index d4bb8ef..3f03ce7 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -20,7 +20,9 @@ /***********/ #include /* for err(3) */ -#if defined(__APPLE__) && defined(__MACH__) + +/* Only need the pthread solution if sigtimedwai(2) isn't available */ +#ifndef H5_HAVE_SIGTIMEDWAIT #include #endif @@ -181,7 +183,7 @@ strsignal(int signum) } #endif -#if defined(__APPLE__) && defined(__MACH__) +#ifndef H5_HAVE_SIGTIMEDWAIT typedef struct timer_params_t { struct timespec *tick; @@ -228,7 +230,7 @@ timer_function(void *arg) return NULL; } -#endif +#endif /* H5_HAVE_SIGTIMEDWAIT */ /* Wait for any signal to occur and then return. Wake periodically * during the wait to perform API calls: in this way, the @@ -254,10 +256,10 @@ await_signal(hid_t fid) dbgf(1, "waiting for signal\n"); -#if defined(__APPLE__) && defined(__MACH__) +#ifndef H5_HAVE_SIGTIMEDWAIT { - /* MacOS does not have sigtimedwait(2), so use an alternative. - * XXX: Replace with configure macros later. + /* Use an alternative scheme for platforms like MacOS that do not have + * sigtimedwait(2) */ timer_params_t params; int rc; @@ -308,7 +310,7 @@ await_signal(hid_t fid) } else if (rc == -1) err(EXIT_FAILURE, "%s: sigtimedwait", __func__); } -#endif +#endif /* H5_HAVE_SIGTIMEDWAIT */ } /* Revised support routines that can be used for all VFD SWMR integration tests -- cgit v0.12 From fa87a22f82437aad67ce7601b0dddead76f12c22 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 14:24:50 -0800 Subject: Fixes the MANIFEST Also renames "SWMR Example.png" to SWMR_Example.png since the MANIFEST doesn't deal with spaces very well. --- MANIFEST | 29 ++++++++++++++++++++++++++++- doc/SWMR Example.png | Bin 81265 -> 0 bytes doc/SWMR_Example.png | Bin 0 -> 81265 bytes 3 files changed, 28 insertions(+), 1 deletion(-) delete mode 100644 doc/SWMR Example.png create mode 100644 doc/SWMR_Example.png diff --git a/MANIFEST b/MANIFEST index 4b14d3f..66de8f2 100644 --- a/MANIFEST +++ b/MANIFEST @@ -185,6 +185,14 @@ ./config/site-specific/BlankForm +./doc/Diagnostic-Logging.md +./doc/SWMR_Example.png +./doc/SWMRdataflow.png +./doc/VFD_SWMR_Punch_List.md +./doc/VFD_SWMR_RFC_200916.docx +./doc/VFD_SWMR_RFC_200916.pdf +./doc/VFD_SWMR_RFC_2020-02-03.docx +./doc/vfd-swmr-user-guide.md ./doc/code-conventions.md ./examples/Attributes.txt @@ -667,6 +675,7 @@ ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5Ftest.c +./src/H5Fvfd_swmr.c ./src/H5FA.c ./src/H5FAcache.c ./src/H5FAdbg.c @@ -716,6 +725,8 @@ ./src/H5FDstdio.c ./src/H5FDstdio.h ./src/H5FDtest.c +./src/H5FDvfd_swmr_instr.c +./src/H5FDvfd_swmr_private.h ./src/H5FDvfd_swmr.c ./src/H5FDvfd_swmr.h ./src/H5FDwindows.c @@ -783,6 +794,7 @@ ./src/H5HGpkg.h ./src/H5HGprivate.h ./src/H5HGquery.c +./src/H5HGtrap.c ./src/H5HL.c ./src/H5HLcache.c ./src/H5HLdbg.c @@ -1020,10 +1032,13 @@ ./src/H5Zshuffle.c ./src/H5Zszip.c ./src/H5Ztrans.c +./src/H5queue.h +./src/H5retry_private.h +./src/H5time_private.h +./src/H5win32defs.h ./src/Makefile.am ./src/hdf5.h ./src/libhdf5.settings.in -./src/H5win32defs.h ./test/AtomicWriterReader.txt ./test/COPYING @@ -1188,6 +1203,8 @@ # ====end distribute this for now. See HDFFV-8236==== ./test/specmetaread.h5 ./test/stab.c +./test/stubs.c +./test/supervise.subr ./test/swmr.c ./test/swmr_addrem_writer.c ./test/swmr_check_compat_vfd.c @@ -1285,8 +1302,18 @@ ./test/vfd_swmr_common.c ./test/vfd_swmr_common.h ./test/vfd_swmr_generator.c +./test/vfd_swmr_addrem_writer.c +./test/vfd_swmr_bigset_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/vfd_swmr_zoo_writer.c ./test/vfd.c ./test/vol.c ./test/vol_plugin.c diff --git a/doc/SWMR Example.png b/doc/SWMR Example.png deleted file mode 100644 index e35624c..0000000 Binary files a/doc/SWMR Example.png and /dev/null differ diff --git a/doc/SWMR_Example.png b/doc/SWMR_Example.png new file mode 100644 index 0000000..e35624c Binary files /dev/null and b/doc/SWMR_Example.png differ -- cgit v0.12 From 3d90a076fb7a2faecd6f1bba2d6da42db565d0a7 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 14:31:16 -0800 Subject: Fixes include guards for a few headers --- src/H5retry_private.h | 6 +++--- src/H5time_private.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/H5retry_private.h b/src/H5retry_private.h index 6621957..45ba8d2 100644 --- a/src/H5retry_private.h +++ b/src/H5retry_private.h @@ -9,8 +9,8 @@ * help@hdfgroup.org. */ -#ifndef _H5retry_private_H -#define _H5retry_private_H +#ifndef H5retry_private_H +#define H5retry_private_H /* * Data types and functions for retry loops. @@ -111,4 +111,4 @@ h5_retry_tries(struct h5_retry_t *r) return r->maxtries - r->tries; } -#endif /* _H5retry_private_H */ +#endif /* H5retry_private_H */ diff --git a/src/H5time_private.h b/src/H5time_private.h index 30cbaf1..603c273 100644 --- a/src/H5time_private.h +++ b/src/H5time_private.h @@ -73,8 +73,8 @@ * @(#)time.h 8.5 (Berkeley) 5/4/95 */ -#ifndef _H5time_private_H -#define _H5time_private_H +#ifndef H5time_private_H +#define H5time_private_H #ifdef __NetBSD__ #include @@ -106,4 +106,4 @@ #define timespec2ns(x) (((uint64_t)(x)->tv_sec) * 1000000000UL + (uint64_t)(x)->tv_nsec) #endif -#endif /* _H5time_private_H */ +#endif /* H5time_private_H */ -- cgit v0.12 From d9f44665cd19620118cd5f6a4fdfac5050200e70 Mon Sep 17 00:00:00 2001 From: vchoi Date: Mon, 1 Mar 2021 18:10:07 -0600 Subject: Revert "Add the two VFD SWMR demo programs to the test directory so that they can be built as needed." This reverts commit f6e7edcedf0339bd18ca0a995f9877a778180f5f. --- MANIFEST | 1 - configure.ac | 10 - m4/ax_with_curses.m4 | 571 ----------------------------------- test/Makefile.am | 16 +- test/vfd_swmr_common.c | 19 -- test/vfd_swmr_common.h | 9 - test/vfd_swmr_credel.c | 483 ----------------------------- test/vfd_swmr_gaussians.c | 753 ---------------------------------------------- 8 files changed, 1 insertion(+), 1861 deletions(-) delete mode 100644 m4/ax_with_curses.m4 delete mode 100644 test/vfd_swmr_credel.c delete mode 100644 test/vfd_swmr_gaussians.c diff --git a/MANIFEST b/MANIFEST index d493763..4b14d3f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -56,7 +56,6 @@ ./m4/ax_prog_javah.m4 ./m4/ax_try_compile_java.m4 ./m4/ax_try_run_java.m4 -./m4/ax_with_curses.m4 ./bin/COPYING ./bin/bbrelease _DO_NOT_DISTRIBUTE_ diff --git a/configure.ac b/configure.ac index 76d8f3e..a641a45 100644 --- a/configure.ac +++ b/configure.ac @@ -1439,15 +1439,6 @@ case "X-$withval" in esac ## ---------------------------------------------------------------------- -## Check if the CURSES library is present. -## This is required to build one of the VFD SWMR demo program. -## -AX_WITH_CURSES -if test "x$ax_cv_curses" != xyes; then - AC_MSG_ERROR([A curses library is required to build the VFD SWMR demo: vfd_swmr_gaussians]) -fi - -## ---------------------------------------------------------------------- ## Make the external filters list available to *.in files ## At this point it's unset (no external filters by default) but it ## will be filled in during the deflate (zlib) and szip processing @@ -3737,7 +3728,6 @@ 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"]) - ## ---------------------------------------------------------------------- ## Build the Makefiles. ## diff --git a/m4/ax_with_curses.m4 b/m4/ax_with_curses.m4 deleted file mode 100644 index 945a626..0000000 --- a/m4/ax_with_curses.m4 +++ /dev/null @@ -1,571 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_with_curses.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_WITH_CURSES -# -# DESCRIPTION -# -# This macro checks whether a SysV or X/Open-compatible Curses library is -# present, along with the associated header file. The NcursesW -# (wide-character) library is searched for first, followed by Ncurses, -# then the system-default plain Curses. The first library found is the -# one returned. Finding libraries will first be attempted by using -# pkg-config, and should the pkg-config files not be available, will -# fallback to combinations of known flags itself. -# -# The following options are understood: --with-ncursesw, --with-ncurses, -# --without-ncursesw, --without-ncurses. The "--with" options force the -# macro to use that particular library, terminating with an error if not -# found. The "--without" options simply skip the check for that library. -# The effect on the search pattern is: -# -# (no options) - NcursesW, Ncurses, Curses -# --with-ncurses --with-ncursesw - NcursesW only [*] -# --without-ncurses --with-ncursesw - NcursesW only [*] -# --with-ncursesw - NcursesW only [*] -# --with-ncurses --without-ncursesw - Ncurses only [*] -# --with-ncurses - NcursesW, Ncurses [**] -# --without-ncurses --without-ncursesw - Curses only -# --without-ncursesw - Ncurses, Curses -# --without-ncurses - NcursesW, Curses -# -# [*] If the library is not found, abort the configure script. -# -# [**] If the second library (Ncurses) is not found, abort configure. -# -# The following preprocessor symbols may be defined by this macro if the -# appropriate conditions are met: -# -# HAVE_CURSES - if any SysV or X/Open Curses library found -# HAVE_CURSES_ENHANCED - if library supports X/Open Enhanced functions -# HAVE_CURSES_COLOR - if library supports color (enhanced functions) -# HAVE_CURSES_OBSOLETE - if library supports certain obsolete features -# HAVE_NCURSESW - if NcursesW (wide char) library is to be used -# HAVE_NCURSES - if the Ncurses library is to be used -# -# HAVE_CURSES_H - if is present and should be used -# HAVE_NCURSESW_H - if should be used -# HAVE_NCURSES_H - if should be used -# HAVE_NCURSESW_CURSES_H - if should be used -# HAVE_NCURSES_CURSES_H - if should be used -# -# (These preprocessor symbols are discussed later in this document.) -# -# The following output variables are defined by this macro; they are -# precious and may be overridden on the ./configure command line: -# -# CURSES_LIBS - library to add to xxx_LDADD -# CURSES_CFLAGS - include paths to add to xxx_CPPFLAGS -# -# In previous versions of this macro, the flags CURSES_LIB and -# CURSES_CPPFLAGS were defined. These have been renamed, in keeping with -# AX_WITH_CURSES's close bigger brother, PKG_CHECK_MODULES, which should -# eventually supersede the use of AX_WITH_CURSES. Neither the library -# listed in CURSES_LIBS, nor the flags in CURSES_CFLAGS are added to LIBS, -# respectively CPPFLAGS, by default. You need to add both to the -# appropriate xxx_LDADD/xxx_CPPFLAGS line in your Makefile.am. For -# example: -# -# prog_LDADD = @CURSES_LIBS@ -# prog_CPPFLAGS = @CURSES_CFLAGS@ -# -# If CURSES_LIBS is set on the configure command line (such as by running -# "./configure CURSES_LIBS=-lmycurses"), then the only header searched for -# is . If the user needs to specify an alternative path for a -# library (such as for a non-standard NcurseW), the user should use the -# LDFLAGS variable. -# -# The following shell variables may be defined by this macro: -# -# ax_cv_curses - set to "yes" if any Curses library found -# ax_cv_curses_enhanced - set to "yes" if Enhanced functions present -# ax_cv_curses_color - set to "yes" if color functions present -# ax_cv_curses_obsolete - set to "yes" if obsolete features present -# -# ax_cv_ncursesw - set to "yes" if NcursesW library found -# ax_cv_ncurses - set to "yes" if Ncurses library found -# ax_cv_plaincurses - set to "yes" if plain Curses library found -# ax_cv_curses_which - set to "ncursesw", "ncurses", "plaincurses" or "no" -# -# These variables can be used in your configure.ac to determine the level -# of support you need from the Curses library. For example, if you must -# have either Ncurses or NcursesW, you could include: -# -# AX_WITH_CURSES -# if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then -# AC_MSG_ERROR([requires either NcursesW or Ncurses library]) -# fi -# -# If any Curses library will do (but one must be present and must support -# color), you could use: -# -# AX_WITH_CURSES -# if test "x$ax_cv_curses" != xyes || test "x$ax_cv_curses_color" != xyes; then -# AC_MSG_ERROR([requires an X/Open-compatible Curses library with color]) -# fi -# -# Certain preprocessor symbols and shell variables defined by this macro -# can be used to determine various features of the Curses library. In -# particular, HAVE_CURSES and ax_cv_curses are defined if the Curses -# library found conforms to the traditional SysV and/or X/Open Base Curses -# definition. Any working Curses library conforms to this level. -# -# HAVE_CURSES_ENHANCED and ax_cv_curses_enhanced are defined if the -# library supports the X/Open Enhanced Curses definition. In particular, -# the wide-character types attr_t, cchar_t and wint_t, the functions -# wattr_set() and wget_wch() and the macros WA_NORMAL and _XOPEN_CURSES -# are checked. The Ncurses library does NOT conform to this definition, -# although NcursesW does. -# -# HAVE_CURSES_COLOR and ax_cv_curses_color are defined if the library -# supports color functions and macros such as COLOR_PAIR, A_COLOR, -# COLOR_WHITE, COLOR_RED and init_pair(). These are NOT part of the -# X/Open Base Curses definition, but are part of the Enhanced set of -# functions. The Ncurses library DOES support these functions, as does -# NcursesW. -# -# HAVE_CURSES_OBSOLETE and ax_cv_curses_obsolete are defined if the -# library supports certain features present in SysV and BSD Curses but not -# defined in the X/Open definition. In particular, the functions -# getattrs(), getcurx() and getmaxx() are checked. -# -# To use the HAVE_xxx_H preprocessor symbols, insert the following into -# your system.h (or equivalent) header file: -# -# #if defined HAVE_NCURSESW_CURSES_H -# # include -# #elif defined HAVE_NCURSESW_H -# # include -# #elif defined HAVE_NCURSES_CURSES_H -# # include -# #elif defined HAVE_NCURSES_H -# # include -# #elif defined HAVE_CURSES_H -# # include -# #else -# # error "SysV or X/Open-compatible Curses header file required" -# #endif -# -# For previous users of this macro: you should not need to change anything -# in your configure.ac or Makefile.am, as the previous (serial 10) -# semantics are still valid. However, you should update your system.h (or -# equivalent) header file to the fragment shown above. You are encouraged -# also to make use of the extended functionality provided by this version -# of AX_WITH_CURSES, as well as in the additional macros -# AX_WITH_CURSES_PANEL, AX_WITH_CURSES_MENU and AX_WITH_CURSES_FORM. -# -# LICENSE -# -# Copyright (c) 2009 Mark Pulford -# Copyright (c) 2009 Damian Pietras -# Copyright (c) 2012 Reuben Thomas -# Copyright (c) 2011 John Zaitseff -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 18 - -# internal function to factorize common code that is used by both ncurses -# and ncursesw -AC_DEFUN([_FIND_CURSES_FLAGS], [ - # THG CHANGES! - # - # In order to avoid a dependency on pkg-conf, that part of this macro - # has been removed. This code always uses the "fallback" option. - - AC_CACHE_CHECK([for $1], [ax_cv_$1], [ - AS_ECHO() - pkg_cv__ax_cv_$1_libs="-l$1" - pkg_cv__ax_cv_$1_cppflags="-D_GNU_SOURCE $CURSES_CFLAGS" - LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs" - CPPFLAGS="$ax_saved_CPPFLAGS $pkg_cv__ax_cv_$1_cppflags" - - AC_MSG_CHECKING([for initscr() with $pkg_cv__ax_cv_$1_libs]) - AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], - [ - AC_MSG_RESULT([yes]) - AC_MSG_CHECKING([for nodelay() with $pkg_cv__ax_cv_$1_libs]) - AC_LINK_IFELSE([AC_LANG_CALL([], [nodelay])],[ - ax_cv_$1=yes - ],[ - AC_MSG_RESULT([no]) - m4_if( - [$1],[ncursesw],[pkg_cv__ax_cv_$1_libs="$pkg_cv__ax_cv_$1_libs -ltinfow"], - [$1],[ncurses],[pkg_cv__ax_cv_$1_libs="$pkg_cv__ax_cv_$1_libs -ltinfo"] - ) - LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs" - - AC_MSG_CHECKING([for nodelay() with $pkg_cv__ax_cv_$1_libs]) - AC_LINK_IFELSE([AC_LANG_CALL([], [nodelay])],[ - ax_cv_$1=yes - ],[ - ax_cv_$1=no - ]) - ]) - ],[ - ax_cv_$1=no - ]) - ]) -]) - -AU_ALIAS([MP_WITH_CURSES], [AX_WITH_CURSES]) -AC_DEFUN([AX_WITH_CURSES], [ - AC_ARG_VAR([CURSES_LIBS], [linker library for Curses, e.g. -lcurses]) - AC_ARG_VAR([CURSES_CFLAGS], [preprocessor flags for Curses, e.g. -I/usr/include/ncursesw]) - AC_ARG_WITH([ncurses], [AS_HELP_STRING([--with-ncurses], - [force the use of Ncurses or NcursesW])], - [], [with_ncurses=check]) - AC_ARG_WITH([ncursesw], [AS_HELP_STRING([--without-ncursesw], - [do not use NcursesW (wide character support)])], - [], [with_ncursesw=check]) - - ax_saved_LIBS=$LIBS - ax_saved_CPPFLAGS=$CPPFLAGS - - AS_IF([test "x$with_ncurses" = xyes || test "x$with_ncursesw" = xyes], - [ax_with_plaincurses=no], [ax_with_plaincurses=check]) - - ax_cv_curses_which=no - - # Test for NcursesW - AS_IF([test "x$CURSES_LIBS" = x && test "x$with_ncursesw" != xno], [ - _FIND_CURSES_FLAGS([ncursesw]) - - AS_IF([test "x$ax_cv_ncursesw" = xno && test "x$with_ncursesw" = xyes], [ - AC_MSG_ERROR([--with-ncursesw specified but could not find NcursesW library]) - ]) - - AS_IF([test "x$ax_cv_ncursesw" = xyes], [ - ax_cv_curses=yes - ax_cv_curses_which=ncursesw - CURSES_LIBS="$pkg_cv__ax_cv_ncursesw_libs" - CURSES_CFLAGS="$pkg_cv__ax_cv_ncursesw_cppflags" - AC_DEFINE([HAVE_NCURSESW], [1], [Define to 1 if the NcursesW library is present]) - AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) - - AC_CACHE_CHECK([for working ncursesw/curses.h], [ax_cv_header_ncursesw_curses_h], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@define _XOPEN_SOURCE_EXTENDED 1 - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - attr_t d = WA_NORMAL; - cchar_t e; - wint_t f; - int g = getattrs(stdscr); - int h = getcurx(stdscr) + getmaxx(stdscr); - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - wattr_set(stdscr, d, 0, NULL); - wget_wch(stdscr, &f); - ]])], - [ax_cv_header_ncursesw_curses_h=yes], - [ax_cv_header_ncursesw_curses_h=no]) - ]) - AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xyes], [ - ax_cv_curses_enhanced=yes - ax_cv_curses_color=yes - ax_cv_curses_obsolete=yes - AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) - AC_DEFINE([HAVE_NCURSESW_CURSES_H], [1], [Define to 1 if is present]) - ]) - - AC_CACHE_CHECK([for working ncursesw.h], [ax_cv_header_ncursesw_h], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@define _XOPEN_SOURCE_EXTENDED 1 - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - attr_t d = WA_NORMAL; - cchar_t e; - wint_t f; - int g = getattrs(stdscr); - int h = getcurx(stdscr) + getmaxx(stdscr); - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - wattr_set(stdscr, d, 0, NULL); - wget_wch(stdscr, &f); - ]])], - [ax_cv_header_ncursesw_h=yes], - [ax_cv_header_ncursesw_h=no]) - ]) - AS_IF([test "x$ax_cv_header_ncursesw_h" = xyes], [ - ax_cv_curses_enhanced=yes - ax_cv_curses_color=yes - ax_cv_curses_obsolete=yes - AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) - AC_DEFINE([HAVE_NCURSESW_H], [1], [Define to 1 if is present]) - ]) - - AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h_with_ncursesw], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@define _XOPEN_SOURCE_EXTENDED 1 - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - attr_t d = WA_NORMAL; - cchar_t e; - wint_t f; - int g = getattrs(stdscr); - int h = getcurx(stdscr) + getmaxx(stdscr); - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - wattr_set(stdscr, d, 0, NULL); - wget_wch(stdscr, &f); - ]])], - [ax_cv_header_ncurses_h_with_ncursesw=yes], - [ax_cv_header_ncurses_h_with_ncursesw=no]) - ]) - AS_IF([test "x$ax_cv_header_ncurses_h_with_ncursesw" = xyes], [ - ax_cv_curses_enhanced=yes - ax_cv_curses_color=yes - ax_cv_curses_obsolete=yes - AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) - AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if is present]) - ]) - - AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xno && test "x$ax_cv_header_ncursesw_h" = xno && test "x$ax_cv_header_ncurses_h_with_ncursesw" = xno], [ - AC_MSG_WARN([could not find a working ncursesw/curses.h, ncursesw.h or ncurses.h]) - ]) - ]) - ]) - unset pkg_cv__ax_cv_ncursesw_libs - unset pkg_cv__ax_cv_ncursesw_cppflags - - # Test for Ncurses - AS_IF([test "x$CURSES_LIBS" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [ - _FIND_CURSES_FLAGS([ncurses]) - - AS_IF([test "x$ax_cv_ncurses" = xno && test "x$with_ncurses" = xyes], [ - AC_MSG_ERROR([--with-ncurses specified but could not find Ncurses library]) - ]) - - AS_IF([test "x$ax_cv_ncurses" = xyes], [ - ax_cv_curses=yes - ax_cv_curses_which=ncurses - CURSES_LIBS="$pkg_cv__ax_cv_ncurses_libs" - CURSES_CFLAGS="$pkg_cv__ax_cv_ncurses_cppflags" - AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if the Ncurses library is present]) - AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) - - AC_CACHE_CHECK([for working ncurses/curses.h], [ax_cv_header_ncurses_curses_h], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - int g = getattrs(stdscr); - int h = getcurx(stdscr) + getmaxx(stdscr); - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - ]])], - [ax_cv_header_ncurses_curses_h=yes], - [ax_cv_header_ncurses_curses_h=no]) - ]) - AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xyes], [ - ax_cv_curses_color=yes - ax_cv_curses_obsolete=yes - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) - AC_DEFINE([HAVE_NCURSES_CURSES_H], [1], [Define to 1 if is present]) - ]) - - AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - int g = getattrs(stdscr); - int h = getcurx(stdscr) + getmaxx(stdscr); - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - ]])], - [ax_cv_header_ncurses_h=yes], - [ax_cv_header_ncurses_h=no]) - ]) - AS_IF([test "x$ax_cv_header_ncurses_h" = xyes], [ - ax_cv_curses_color=yes - ax_cv_curses_obsolete=yes - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) - AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if is present]) - ]) - - AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xno && test "x$ax_cv_header_ncurses_h" = xno], [ - AC_MSG_WARN([could not find a working ncurses/curses.h or ncurses.h]) - ]) - ]) - ]) - unset pkg_cv__ax_cv_ncurses_libs - unset pkg_cv__ax_cv_ncurses_cppflags - - # Test for plain Curses (or if CURSES_LIBS was set by user) - AS_IF([test "x$with_plaincurses" != xno && test "x$ax_cv_curses_which" = xno], [ - AS_IF([test "x$CURSES_LIBS" != x], [ - LIBS="$ax_saved_LIBS $CURSES_LIBS" - ], [ - LIBS="$ax_saved_LIBS -lcurses" - ]) - - AC_CACHE_CHECK([for Curses library], [ax_cv_plaincurses], [ - AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])], - [ax_cv_plaincurses=yes], [ax_cv_plaincurses=no]) - ]) - - AS_IF([test "x$ax_cv_plaincurses" = xyes], [ - ax_cv_curses=yes - ax_cv_curses_which=plaincurses - AS_IF([test "x$CURSES_LIBS" = x], [ - CURSES_LIBS="-lcurses" - ]) - AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present]) - - # Check for base conformance (and header file) - - AC_CACHE_CHECK([for working curses.h], [ax_cv_header_curses_h], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - initscr(); - ]])], - [ax_cv_header_curses_h=yes], - [ax_cv_header_curses_h=no]) - ]) - AS_IF([test "x$ax_cv_header_curses_h" = xyes], [ - AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if is present]) - - # Check for X/Open Enhanced conformance - - AC_CACHE_CHECK([for X/Open Enhanced Curses conformance], [ax_cv_plaincurses_enhanced], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@define _XOPEN_SOURCE_EXTENDED 1 - @%:@include - @%:@ifndef _XOPEN_CURSES - @%:@error "this Curses library is not enhanced" - "this Curses library is not enhanced" - @%:@endif - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - attr_t d = WA_NORMAL; - cchar_t e; - wint_t f; - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - wattr_set(stdscr, d, 0, NULL); - wget_wch(stdscr, &f); - ]])], - [ax_cv_plaincurses_enhanced=yes], - [ax_cv_plaincurses_enhanced=no]) - ]) - AS_IF([test "x$ax_cv_plaincurses_enhanced" = xyes], [ - ax_cv_curses_enhanced=yes - ax_cv_curses_color=yes - AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions]) - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - ]) - - # Check for color functions - - AC_CACHE_CHECK([for Curses color functions], [ax_cv_plaincurses_color], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@define _XOPEN_SOURCE_EXTENDED 1 - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - chtype c = COLOR_PAIR(1) & A_COLOR; - initscr(); - init_pair(1, COLOR_WHITE, COLOR_RED); - ]])], - [ax_cv_plaincurses_color=yes], - [ax_cv_plaincurses_color=no]) - ]) - AS_IF([test "x$ax_cv_plaincurses_color" = xyes], [ - ax_cv_curses_color=yes - AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)]) - ]) - - # Check for obsolete functions - - AC_CACHE_CHECK([for obsolete Curses functions], [ax_cv_plaincurses_obsolete], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - chtype a = A_BOLD; - int b = KEY_LEFT; - int g = getattrs(stdscr); - int h = getcurx(stdscr) + getmaxx(stdscr); - initscr(); - ]])], - [ax_cv_plaincurses_obsolete=yes], - [ax_cv_plaincurses_obsolete=no]) - ]) - AS_IF([test "x$ax_cv_plaincurses_obsolete" = xyes], [ - ax_cv_curses_obsolete=yes - AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features]) - ]) - ]) - - AS_IF([test "x$ax_cv_header_curses_h" = xno], [ - AC_MSG_WARN([could not find a working curses.h]) - ]) - ]) - ]) - - AS_IF([test "x$ax_cv_curses" != xyes], [ax_cv_curses=no]) - AS_IF([test "x$ax_cv_curses_enhanced" != xyes], [ax_cv_curses_enhanced=no]) - AS_IF([test "x$ax_cv_curses_color" != xyes], [ax_cv_curses_color=no]) - AS_IF([test "x$ax_cv_curses_obsolete" != xyes], [ax_cv_curses_obsolete=no]) - - LIBS=$ax_saved_LIBS - CPPFLAGS=$ax_saved_CPPFLAGS - - unset ax_saved_LIBS - unset ax_saved_CPPFLAGS -])dnl diff --git a/test/Makefile.am b/test/Makefile.am index 0aec03c..2b1d7d5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -120,24 +120,10 @@ endif # --enable-build-all at configure time. # The gen_old_* files can only be compiled with older versions of the library # so do not appear in this list. -# Add the two VFD SWMR demo programs and build it as needed. BUILD_ALL_PROGS=gen_bad_ohdr gen_bogus gen_cross gen_deflate gen_filters gen_new_array \ gen_new_fill gen_new_group gen_new_mtime gen_new_super gen_noencoder \ gen_nullspace gen_udlinks space_overflow gen_filespace gen_specmetaread \ - gen_sizes_lheap gen_file_image gen_plist gen_bad_offset gen_bounds \ - vfd_swmr_gaussians vfd_swmr_credel - -# VFD SWMR demo: vfd_swmr_gaussians needs the curses library -vfd_swmr_gaussians_LDFLAGS=$(AM_LDFLAGS) @CURSES_LIBS@ -vfd_swmr_gaussians=$(AM_CFLAGS) @CURSES_LIBS@ - -# Writer for VFD SWMR demo -w_vfd_swmr_gaussians: vfd_swmr_gaussians - @test -e w_vfd_swmr_gaussians || ln -s vfd_swmr_gaussians w_vfd_swmr_gaussians - -# Reader for VFD SWMR demo -r_vfd_swmr_gaussians: vfd_swmr_gaussians - @test -e r_vfd_swmr_gaussians || ln -s vfd_swmr_gaussians r_vfd_swmr_gaussians + gen_sizes_lheap gen_file_image gen_plist gen_bad_offset gen_bounds if BUILD_ALL_CONDITIONAL noinst_PROGRAMS=$(BUILD_ALL_PROGS) diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index 9352a37..3f03ce7 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -418,22 +418,3 @@ fetch_env_ulong(const char *varname, unsigned long limit, unsigned long *valp) *valp = ul; return 1; } - -/* - * For demo credel.c: need to write up description - */ -size_t -strlcpy(char *dst, const char *src, size_t size) -{ - char *d; - const char *s; - - for (d = dst, s = src; (s - src) < (int)size; d++, s++) { - *d = *s; - if (*s == '\0') - return (size_t) (s - src); - } - - dst[size - 1] = '\0'; - return size; -} diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index bbcb28a..f64ee87 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -19,7 +19,6 @@ /***********/ #include -#include /* For demo */ #include "h5test.h" /**********/ @@ -36,11 +35,6 @@ /* The message sent by writer that the file open is done--releasing the file lock */ #define VFD_SWMR_WRITER_MESSAGE "VFD_SWMR_WRITER_MESSAGE" -/* For demo */ -#ifndef __arraycount -#define __arraycount(__a) (sizeof(__a) / sizeof((__a)[0])) -#endif - /************/ /* Typedefs */ /************/ @@ -94,9 +88,6 @@ H5TEST_DLL void esnprintf(char *, size_t, const char *, ...) H5TEST_DLL int fetch_env_ulong(const char *, unsigned long, unsigned long *); -/* For demo */ -H5TEST_DLL size_t strlcpy(char *, const char *, size_t); - #ifdef __cplusplus } #endif diff --git a/test/vfd_swmr_credel.c b/test/vfd_swmr_credel.c deleted file mode 100644 index fe6f0d5..0000000 --- a/test/vfd_swmr_credel.c +++ /dev/null @@ -1,483 +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://support.hdfgroup.org/ftp/HDF5/releases. - * If you do not have access to either file, you may request a copy from - * help@hdfgroup.org. - */ - -#include -#include -#include -#include /* basename(3) */ -#include -#include -#include -#include -#include /* struct timespec, nanosleep */ -#include /* getopt, PATH_MAX, ... */ - -#include "hdf5.h" -#include "vfd_swmr_common.h" - -#define DATAROWS 1 -#define DATACOLS 10 -static const hsize_t dims[2] = {DATAROWS, DATACOLS}; -static const hsize_t chunk_dims[2] = {1, 1}; -static volatile sig_atomic_t unbroken = 1; - -typedef struct { - uint64_t created, deleted; -} stats_pair_t; - -typedef struct { - stats_pair_t datasets, groups; - uint64_t iterations; -} stats_t; - -typedef struct { - hid_t dataset[4], dataspace, dapl, dcpl, file, group[2]; - char output_file[PATH_MAX]; - char progname[PATH_MAX]; - struct timespec update_interval; - int verbose; - bool oneshot; - bool print_stats; - bool use_vfd_swmr; - uint64_t iterations_limit; - stats_t stats; -} state_t; - -#define ALL_HID_INITIALIZER (state_t){ \ - .dataspace = H5I_INVALID_HID \ - , .file = H5I_INVALID_HID \ - , .verbose = 0 \ - , .oneshot = false \ - , .use_vfd_swmr = true \ - , .print_stats = false \ - , .iterations_limit = UINT64_MAX \ - , .output_file = "" \ - , .update_interval = (struct timespec){ \ - .tv_sec = 0 \ - , .tv_nsec = 1000000000UL / 10 /* 1/10 second */} \ - , .stats = {{0, 0}, {0, 0}}} - -static void state_init(state_t *, int, char **); - -static void -write_dataset(state_t *s, const int64_t didx) -{ - const int ndatasets = __arraycount(s->dataset); - hid_t ds; - int32_t data[DATAROWS][DATACOLS]; - herr_t status; - unsigned int i, j; - - for (i = 0; i < (int)__arraycount(data); i++) { - for (j = 0; j < (int)__arraycount(data[i]); j++) { - int64_t k = (didx + j + i ) % (int64_t)__arraycount(data[i]); - - data[i][j] = (0 <= k && k < 3) ? 1 : 0; - if (s->verbose > 1) - fprintf(stderr, " %" PRId32, data[i][j]); - } - if (s->verbose > 1) - fprintf(stderr, "\n"); - } - - ds = s->dataset[didx % ndatasets]; - status = H5Dwrite(ds, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, - H5P_DEFAULT, data); - - if (status < 0) - errx(EXIT_FAILURE, "H5Dwrite failed"); - - if (H5Dflush(ds) < 0) - errx(EXIT_FAILURE, "H5Dflush failed"); -} - -static void -usage(const char *progname) -{ - fprintf(stderr, "usage: %s [-u milliseconds]\n" - "\n" - "-o: oneshot mode, perform one iteration, wait for a signal, " - "then quit.\n" - "-s: print statistics at end\n" - "-S: disable VFD SWMR mode\n" - "-u ms: milliseconds interval between updates to %s.h5\n" - "-v: verbose mode, mention creation/deletion; -vv: print data\n" - "\n", - progname, progname); - exit(EXIT_FAILURE); -} - -static void -print_stats(stats_t *s) -{ - printf("%10" PRIu64 " groups created\n", s->groups.created); - printf("%10" PRIu64 " groups deleted\n", s->groups.deleted); - printf("%10" PRIu64 " datasets created\n", s->datasets.created); - printf("%10" PRIu64 " datasets deleted\n", s->datasets.deleted); - printf("%10" PRIu64 " iterations\n", s->iterations); -} - -static void -state_init(state_t *s, int argc, char **argv) -{ - int ch, i, rc; - char tfile[PATH_MAX]; - char *end; - unsigned long millis; - uintmax_t niters; - - *s = ALL_HID_INITIALIZER; - strlcpy(tfile, argv[0], sizeof(tfile)); - strlcpy(s->progname, basename(tfile), sizeof(s->progname)); - while ((ch = getopt(argc, argv, "n:ou:sSv")) != -1) { - switch (ch) { - case 'n': - niters = strtoumax(optarg, &end, 0); - if (niters == UINTMAX_MAX && errno == ERANGE) { - err(EXIT_FAILURE, "option -%c argument \"%s\"", - ch, optarg); - } else if (*end != '\0') { - errx(EXIT_FAILURE, - "garbage after -%c argument \"%s\"", ch, - optarg); - } - s->iterations_limit = niters; - break; - case 'o': - s->oneshot = true; - break; - case 's': - s->print_stats = true; - break; - case 'S': - s->use_vfd_swmr = false; - break; - case 'u': - errno = 0; - millis = strtoul(optarg, &end, 0); - if (millis == ULONG_MAX && errno == ERANGE) { - err(EXIT_FAILURE, "option -%c argument \"%s\"", - ch, optarg); - } else if (*end != '\0') { - errx(EXIT_FAILURE, - "garbage after -%c argument \"%s\"", ch, - optarg); - } - s->update_interval.tv_sec = (time_t)(millis / 1000UL); - s->update_interval.tv_nsec = (long)((millis * 1000000UL) % 1000000000UL); - warnx("%lu milliseconds between updates", millis); - break; - case 'v': - s->verbose++; - break; - case '?': - default: - usage(s->progname); - } - } - argc -= optind; - argv += optind; - - for (i = 0; i < (int)__arraycount(s->dataset); i++) - s->dataset[i] = H5I_INVALID_HID; - - for (i = 0; i < (int)__arraycount(s->group); i++) - s->group[i] = H5I_INVALID_HID; - - rc = snprintf(s->output_file, sizeof(s->output_file), "%s.h5", s->progname); - if (rc == -1 || rc >= (int)sizeof(s->output_file)) - errx(EXIT_FAILURE, "output filename was truncated"); -} - -static void -delete_group(state_t *s, const int64_t gidx) -{ - hid_t g; - const int ngroups = __arraycount(s->group); - char gname[32]; - - assert(0 <= gidx); - - snprintf(gname, sizeof(gname), "/group-%" PRId64, gidx); - g = s->group[gidx % ngroups]; - - if (H5Ldelete(s->file, gname, H5P_DEFAULT) < 0) { - errx(EXIT_FAILURE, "%s: H5Ldelete(, \"%s\", ) failed", - __func__, gname); - } - - if (H5Gclose(g) < 0) - errx(EXIT_FAILURE, "H5Gclose failed"); - - if (s->verbose > 0) - fprintf(stderr, "Deleted group %s\n", gname); - - s->group[gidx % ngroups] = H5I_INVALID_HID; - s->stats.groups.deleted++; -} - -static void -create_group(state_t *s, const int64_t gidx) -{ - const int ngroups = __arraycount(s->group); - hid_t g; - char gname[32]; - - assert(0 <= gidx); - assert(s->group[gidx % ngroups] == H5I_INVALID_HID); - - snprintf(gname, sizeof(gname), "/group-%" PRId64, gidx); - g = H5Gcreate(s->file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - if (g < 0) - errx(EXIT_FAILURE, "H5Gcreate failed"); - - if (s->verbose > 0) - fprintf(stderr, "Created group %s\n", gname); - s->group[gidx % ngroups] = g; - s->stats.groups.created++; -} - -static void -delete_dataset(state_t *s, const int64_t didx) -{ - const int ndatasets = __arraycount(s->dataset); - const hid_t ds = s->dataset[didx % ndatasets]; - char dname[32]; - const int64_t gidx = didx / 2; - - assert(0 <= gidx && 0 <= didx); - - snprintf(dname, sizeof(dname), "/group-%" PRId64 "/dataset-%" PRId64, - gidx, didx); - if (H5Ldelete(s->file, dname, H5P_DEFAULT) < 0) { - errx(EXIT_FAILURE, "%s: H5Ldelete(, \"%s\", ) failed", - __func__, dname); - } - - if (s->verbose > 0) - fprintf(stderr, "Deleted dataset %s\n", dname); -#if 1 - if (H5Dclose(ds) < 0) - errx(EXIT_FAILURE, "H5Dclose failed"); -#endif - s->dataset[didx % ndatasets] = H5I_INVALID_HID; - s->stats.datasets.deleted++; -} - -static void -create_dataset(state_t *s, const int64_t didx) -{ - const int ndatasets = __arraycount(s->dataset); - char dname[32]; - const int64_t gidx = didx / 2; - hid_t ds; - - assert(0 <= gidx && 0 <= didx); - assert(s->dataset[didx % ndatasets] == H5I_INVALID_HID); - - s->dataspace = H5Screate_simple(__arraycount(dims), dims, NULL); - - if (s->dataspace < 0) - errx(EXIT_FAILURE, "H5Screate_simple failed"); - - snprintf(dname, sizeof(dname), "/group-%" PRId64 "/dataset-%" PRId64, - gidx, didx); - ds = H5Dcreate2(s->file, dname, - H5T_STD_I32BE, s->dataspace, - H5P_DEFAULT, s->dcpl, s->dapl); - - if (H5Sclose(s->dataspace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); - - s->dataspace = H5I_INVALID_HID; - - if (ds < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); - - if (s->verbose > 0) - fprintf(stderr, "Created dataset %s\n", dname); - s->dataset[didx % ndatasets] = ds; - s->stats.datasets.created++; -} - -static void -create_and_write_dataset(state_t *s, const int64_t didx) -{ -#if 0 - const int64_t gidx = didx / 2; - const int ngroups = __arraycount(s->group); - const hid_t g = s->group[gidx % ngroups]; - - if (H5Odisable_mdc_flushes(g) < 0) - err(EXIT_FAILURE, "H5Odisable_mdc_flushes failed"); -#endif - - create_dataset(s, didx); - write_dataset(s, didx); - -#if 0 - if (H5Oenable_mdc_flushes(g) < 0) - err(EXIT_FAILURE, "H5Oenable_mdc_flushes failed"); -#endif -} - -static void -handle_signal(int H5_ATTR_UNUSED signo) -{ - char msg[] = "Handling signal\n"; - write(STDERR_FILENO, msg, sizeof(msg) - 1); - unbroken = 0; -} - -static void -disestablish_handler(const struct sigaction *osa) -{ - if (sigaction(SIGINT, osa, NULL) == -1) - err(EXIT_FAILURE, "%s: sigaction", __func__); -} - -static void -establish_handler(struct sigaction *osa) -{ - struct sigaction sa; - - memset(&sa, '\0', sizeof(sa)); - sa.sa_handler = handle_signal; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGINT, &sa, osa) == -1) - err(EXIT_FAILURE, "%s: sigaction", __func__); -} - -int -main(int argc, char **argv) -{ - hid_t fapl, fcpl; - struct sigaction osa; - state_t storage; - state_t *s = &storage; - int64_t i; - H5F_vfd_swmr_config_t config; - - memset(&config, '\0', sizeof(config)); - - state_init(s, argc, argv); - - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 5, true, FALSE, 128, "./my_md_file"); - - /* use_latest_format, use_vfd_swmr, only_meta_page, config */ - fapl = vfd_swmr_create_fapl(false, s->use_vfd_swmr, true, &config); - if (fapl < 0) { - errx(EXIT_FAILURE, "%s.%d vfd_swmr_create_fapl failed", - __func__, __LINE__); - } - - fcpl = H5Pcreate(H5P_FILE_CREATE); - if (fcpl < 0) { - errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", - __func__, __LINE__); - } - - /* Set file space strategy to paged aggregation in fcpl. - * Page buffering *requires* this strategy. - * - * I set the free-space threshold to 1GB so that deleted - * datasets are not recycled. - */ - if (H5Pset_file_space_strategy(fcpl, - H5F_FSPACE_STRATEGY_PAGE, false, 1024 * 1024 * 1024) < 0) - errx(EXIT_FAILURE, "H5Pset_file_space_strategy failed"); - - s->file = H5Fcreate(s->output_file, H5F_ACC_TRUNC, fcpl, fapl); - - H5Pclose(fapl); - - if (s->file < 0) - errx(EXIT_FAILURE, "H5Fcreate failed"); - - if ((s->dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", - __func__, __LINE__); - } - if ((s->dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", - __func__, __LINE__); - } - if (H5Pset_chunk(s->dcpl, 2, chunk_dims) < 0) - errx(EXIT_FAILURE, "H5Pset_chunk failed"); - if (H5Pset_chunk_cache(s->dapl, H5D_CHUNK_CACHE_NSLOTS_DEFAULT, 0, - H5D_CHUNK_CACHE_W0_DEFAULT) < 0) - errx(EXIT_FAILURE, "H5Pset_chunk_cache failed"); - - establish_handler(&osa); - - for (i = 0; i < 4; i++) { - s->stats.iterations++; - if (i % 2 == 0) - create_group(s, i / 2); - create_and_write_dataset(s, i); - } - - for (i = 5; unbroken; i += 2) { - delete_dataset(s, i - 5); - delete_dataset(s, i - 4); - delete_group(s, (i - 4) / 2); - create_group(s, i / 2); - create_and_write_dataset(s, i - 1); - create_and_write_dataset(s, i); - if (s->oneshot || ++s->stats.iterations >= s->iterations_limit) - break; - nanosleep(&s->update_interval, NULL); - } - - if (s->oneshot) { - sigset_t mask; - sigemptyset(&mask); - H5Fvfd_swmr_end_tick(s->file); - (void)sigsuspend(&mask); - } -#if 0 - fprintf(stderr, "Interrupted. Cleaning up.\n"); - - int j; - for (--i, j = 0; j < 4; j++, --i) { - if (i % 2 == 1) { - delete_dataset(s, i - 1); - delete_dataset(s, i); - delete_group(s, i / 2); - } - } - - for (j = 0; j < 4; j++) { - assert(s->dataset[j] == H5I_INVALID_HID); - assert(s->group[j / 2] == H5I_INVALID_HID); - } -#endif - - if (s->print_stats) - print_stats(&s->stats); - - if (H5Fclose(s->file) < 0) - errx(EXIT_FAILURE, "H5Fclose failed"); - - if (H5Pclose(s->dapl) < 0) - errx(EXIT_FAILURE, "H5Pclose failed"); - - if (H5Pclose(s->dcpl) < 0) - errx(EXIT_FAILURE, "H5Pclose failed"); - - disestablish_handler(&osa); - - return EXIT_SUCCESS; -} diff --git a/test/vfd_swmr_gaussians.c b/test/vfd_swmr_gaussians.c deleted file mode 100644 index 17231a9..0000000 --- a/test/vfd_swmr_gaussians.c +++ /dev/null @@ -1,753 +0,0 @@ -#include -#include -#include -#include -#include /* basename(3) */ -#include /* expf(3) */ -#include /* setlocale(3) */ -#include -#include -#include -#include -#include /* struct timespec, nanosleep(2), time(3), - * clock_gettime(2) - */ -#include /* getopt, PATH_MAX, ... */ - -#include /* for MIN(a, b) */ - -#include "hdf5.h" -#include "vfd_swmr_common.h" -#include "H5time_private.h" - -#define SWMR_TICK_LEN 4 /* in 100 ms */ - -typedef enum { - STANDALONE = 0 - , READ = 1 - , WRITE = 2 -} personality_t; - -typedef enum { - TOP = 0 - , BOTTOM - , LEFT - , RIGHT - , NSIDES -} side_t; - -typedef struct { - bool side[NSIDES]; -} inside_t; - -typedef struct { - float x, y; -} vec_t; - -#define RANK 3 -#define ROWS 20 -#define COLS 40 -static const hsize_t original_dims[RANK] = {0, ROWS, COLS}; -static const hsize_t max_dims[RANK] = {H5S_UNLIMITED, ROWS, COLS}; -static const hsize_t frame_dims[RANK] = {1, ROWS, COLS}; -static const hsize_t *chunk_dims = frame_dims; -static volatile sig_atomic_t unbroken = 1; - -typedef struct { - /* main-loop statistics */ - uint64_t max_elapsed_ns, min_elapsed_ns, total_elapsed_ns; - uint64_t total_loops; - hid_t dataset, memspace, dcpl, file, group; - char output_file[PATH_MAX]; - char progname[PATH_MAX]; - struct timespec update_interval; - bool fuzz; - bool constantrate; - unsigned int partstep; -} state_t; - -#define ALL_HID_INITIALIZER (state_t){ \ - .total_elapsed_ns = 0 \ - , .total_loops = 0 \ - , .min_elapsed_ns = UINT64_MAX \ - , .max_elapsed_ns = 0 \ - , .memspace = H5I_INVALID_HID \ - , .file = H5I_INVALID_HID \ - , .constantrate = false \ - , .partstep = 0 \ - , .output_file = "" \ - , .update_interval = (struct timespec){ \ - .tv_sec = 0 \ - , .tv_nsec = 1000000000UL / 30 /* 1/30 second */}} - -static void state_init(state_t *, int, char **); - -static void -usage(const char *progname) -{ - fprintf(stderr, "usage: %s [-u milliseconds]\n" - "\n" - "-c: increase the frame number continously (reader mode)\n" - "-f: add \"fuzz\" (linear noise) to the data (writer mode)\n" - "-u ms: milliseconds interval between updates to %s.h5\n" - "\n", - progname, progname); - exit(EXIT_FAILURE); -} - -static void -state_init(state_t *s, int argc, char **argv) -{ - int ch; - char tfile[PATH_MAX]; - char *end; - unsigned long millis; - int nprinted; - - *s = ALL_HID_INITIALIZER; - strlcpy(tfile, argv[0], sizeof(tfile)); - strlcpy(s->progname, basename(tfile), sizeof(s->progname)); - - while ((ch = getopt(argc, argv, "cfu:")) != -1) { - switch (ch) { - case 'c': - s->constantrate = true; - break; - case 'f': - s->fuzz = true; - 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); - - warnx("%lu milliseconds between updates", millis); - break; - case '?': - default: - usage(s->progname); - } - } - argc -= optind; - argv += optind; - - s->dataset = H5I_INVALID_HID; - s->group = H5I_INVALID_HID; - - s->memspace = H5Screate_simple(RANK, frame_dims, NULL); - - if (s->memspace < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", - __func__, __LINE__); - } - - nprinted = snprintf(s->output_file, sizeof(s->output_file), - "%s.h5", s->progname); - if (nprinted < 0 || nprinted >= (int)sizeof(s->output_file)) { - errx(EXIT_FAILURE, "%s.%d: output filename truncated.", - __func__, __LINE__); - } -} - -static void -matrix_read(state_t *s, int *framenop, float mat[ROWS][COLS]) -{ - hid_t ds, filespace; - herr_t status; - hsize_t dims[RANK]; - int lead; - hssize_t temp; - - const uint64_t update_ms = timespec2ns(&s->update_interval) / 1000000; - const uint32_t tick_ms = SWMR_TICK_LEN * 100; - const uint64_t updates_per_tick = (tick_ms + update_ms - 1) / update_ms; - const uint64_t tmp = 2 * updates_per_tick; - const hssize_t hang_back = (hssize_t)tmp; - const int frameno = *framenop; - hsize_t offset[RANK] = {(hsize_t)frameno, 0, 0}; - - ds = s->dataset; - - if (H5Drefresh(ds) < 0) - errx(EXIT_FAILURE, "H5Drefresh failed"); - - filespace = H5Dget_space(ds); - - if (H5Sget_simple_extent_dims(filespace, dims, NULL) < 0) - errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); - - if (dims[1] != original_dims[1] || dims[2] != original_dims[2]) { - errx(EXIT_FAILURE, "Unexpected dimensions N x %ju x %ju", - (uintmax_t)dims[1], (uintmax_t)dims[2]); - } - - - temp = frameno + hang_back - (hssize_t)dims[0]; - lead = (int)temp; - - if (s->constantrate) { - *framenop = frameno + 1; - } else if (lead > hang_back * 2) { - if (++s->partstep % 3 == 0) - *framenop = frameno + 1; - } else if (lead > 0) { - if (++s->partstep % 2 == 0) - *framenop = frameno + 1; - } else if (lead == 0) { - *framenop = frameno + 1; - } else if (lead < -hang_back * 2) { - /* We're way behind, so jump close to the front. */ - temp = (hssize_t)dims[0] - hang_back; - *framenop = (int)temp; - } else /* lead < 0 */ { - *framenop = frameno + 1; - if (++s->partstep % 2 == 0) - *framenop = frameno + 2; - } - -#if 0 - if (!s->constantrate && (lead < -2 || 2 < lead)) { - int gain = 31250 / 4; - const struct timespec prior_integral = s->update_integral; - struct timespec current_interval; - if (lead > 0) - gain *= 2; - struct timespec adjustment = (struct timespec){.tv_sec = 0, - .tv_nsec = gain * MAX(MIN(4, lead), -4)}; - /* XXX clamp it XXX */ - timespecadd(&s->update_integral, - &adjustment, &s->update_integral); - timespecadd(&s->update_integral, - &s->update_interval, ¤t_interval); - if (timespeccmp(¤t_interval, &s->min_interval, <=)) - s->update_integral = prior_integral; - } -#endif - - if (frameno >= (int)dims[0]) { - int i, j; - for (i = 0; i < ROWS; i++) { - for (j = 0; j < COLS; j++) - mat[i][j] = ((i + j) % 2 == 0) ? 0. : 1.; - } - return; - } - - if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, - frame_dims, NULL) < 0) - errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); - - status = H5Dread(ds, H5T_NATIVE_FLOAT, s->memspace, filespace, - H5P_DEFAULT, mat); - - if (status < 0) - errx(EXIT_FAILURE, "H5Dread failed"); - - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); -} - -static void -matrix_write(state_t *s, int frameno, float mat[ROWS][COLS]) -{ - hid_t ds, filespace; - herr_t status; - hsize_t size[RANK] = {(hsize_t)frameno + 1, ROWS, COLS}; - hsize_t offset[RANK] = {(hsize_t)frameno, 0, 0}; - - ds = s->dataset; - - if (H5Dset_extent(ds, size) < 0) - errx(EXIT_FAILURE, "H5Dset_extent failed"); - - filespace = H5Dget_space(ds); - - if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, - frame_dims, NULL) < 0) - errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); - - status = H5Dwrite(ds, H5T_NATIVE_FLOAT, s->memspace, filespace, - H5P_DEFAULT, mat); - - if (status < 0) - errx(EXIT_FAILURE, "H5Dwrite failed"); - - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); - - if (H5Dflush(ds) < 0) - errx(EXIT_FAILURE, "H5Dflush failed"); -} - -static void -open_group(state_t *s) -{ - hid_t g; - const char *gname = "/group-0"; - - assert(s->group == H5I_INVALID_HID); - - g = H5Gopen(s->file, gname, H5P_DEFAULT); - - if (g < 0) - errx(EXIT_FAILURE, "H5Gcreate failed"); - - fprintf(stderr, "Opened group %s\n", gname); - s->group = g; -} - -static void -create_group(state_t *s) -{ - hid_t g; - const char *gname = "/group-0"; - - assert(s->group == H5I_INVALID_HID); - - g = H5Gcreate(s->file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - - if (g < 0) - errx(EXIT_FAILURE, "H5Gcreate failed"); - - s->group = g; -} - -static void -open_dataset(state_t *s) -{ - const char *dname = "/group-0/dataset-0"; - hid_t ds; - hid_t filespace; - hid_t ty; - hsize_t dims[RANK], maxdims[RANK]; - - assert(s->dataset == H5I_INVALID_HID); - - ds = H5Dopen(s->file, dname, H5P_DEFAULT); - - if (ds < 0) - errx(EXIT_FAILURE, "H5Dopen(, \"%s\", ) failed", dname); - - if ((ty = H5Dget_type(ds)) < 0) - errx(EXIT_FAILURE, "H5Dget_type failed"); - - if (H5Tequal(ty, H5T_IEEE_F32BE) <= 0) - errx(EXIT_FAILURE, "Unexpected data type"); - - if ((filespace = H5Dget_space(ds)) < 0) - errx(EXIT_FAILURE, "H5Dget_space failed"); - - if (H5Sget_simple_extent_ndims(filespace) != RANK) - errx(EXIT_FAILURE, "Unexpected rank"); - - if (H5Sget_simple_extent_dims(filespace, dims, maxdims) < 0) - errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); - - if (dims[1] != original_dims[1] || dims[2] != original_dims[2]) { - errx(EXIT_FAILURE, "Unexpected dimensions ? x %ju x %ju", - (uintmax_t)dims[1], (uintmax_t)dims[2]); - } - - if (maxdims[1] != original_dims[1] || maxdims[2] != original_dims[2]) { - errx(EXIT_FAILURE, - "Unexpected maximum dimensions ? x %ju x %ju", - (uintmax_t)dims[1], (uintmax_t)dims[2]); - } - - fprintf(stderr, "Opened dataset %s\n", dname); - s->dataset = ds; -} - -static void -create_dataset(state_t *s) -{ - const char *dname = "/group-0/dataset-0"; - hid_t ds; - hid_t filespace; - - assert(s->dataset == H5I_INVALID_HID); - - filespace = H5Screate_simple(__arraycount(original_dims), original_dims, - max_dims); - - if (filespace < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", - __func__, __LINE__); - } - - if ((s->dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", - __func__, __LINE__); - } - - if (H5Pset_chunk(s->dcpl, RANK, chunk_dims) < 0) - errx(EXIT_FAILURE, "H5Pset_chunk failed"); - - ds = H5Dcreate2(s->file, dname, H5T_IEEE_F32BE, filespace, - H5P_DEFAULT, s->dcpl, H5P_DEFAULT); - - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); - - filespace = H5I_INVALID_HID; - - if (ds < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); - - s->dataset = ds; -} - -static void -handle_signal(int H5_ATTR_UNUSED signo) -{ - unbroken = 0; -} - -static void -disestablish_handler(const struct sigaction *osa) -{ - if (sigaction(SIGINT, osa, NULL) == -1) - err(EXIT_FAILURE, "%s: sigaction", __func__); -} - -static void -establish_handler(struct sigaction *osa) -{ - struct sigaction sa; - - memset(&sa, '\0', sizeof(sa)); - sa.sa_handler = handle_signal; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGINT, &sa, osa) == -1) - err(EXIT_FAILURE, "%s: sigaction", __func__); -} - -static void -step(vec_t *center, vec_t *direction, float steplen, bool *recursed) -{ - static const float top = 0., bottom = (float)COLS, - left = 0., right = (float)ROWS; - struct { - bool top, bottom, left, right; - } bounce = {false, false, false, false}; - float xback, yback; - vec_t before = *center; - vec_t after = (vec_t){.x = before.x + direction->x * steplen, - .y = before.y + direction->y * steplen}; - - if (before.x < right && after.x >= right) { - xback = (right - before.x) / (after.x - before.x); - bounce.right = true; - } else if (before.x > left && after.x <= left) { - xback = (before.x - left) / (before.x - after.x); - bounce.left = true; - } else - xback = 0.; - - if (before.y < bottom && after.y >= bottom) { - yback = (bottom - before.y) / (after.y - before.y); - bounce.bottom = true; - } else if (before.y > top && after.y <= top) { - yback = (before.y - top) / (before.y - after.y); - bounce.top = true; - } else - yback = 0.; - - /* I shorten the step length until a corner crossing becomes - * a side crossing. - */ - if ((bounce.top && bounce.right) || - (bounce.right && bounce.bottom) || - (bounce.bottom && bounce.left) || - (bounce.left && bounce.top)) { - - float newsteplen = steplen * 2 / 3; - if (recursed != NULL) - *recursed = true; - step(center, direction, newsteplen, NULL); - step(center, direction, steplen - newsteplen, NULL); - } - if (bounce.right || bounce.left) { - after.x = before.x + direction->x * (2 * xback - 1) * steplen; - direction->x = -direction->x; - } - if (bounce.top || bounce.bottom) { - after.y = before.y + direction->y * (2 * yback - 1) * steplen; - direction->y = -direction->y; - } - *center = after; -} - -static float -gaussian(float x, float y, float r) -{ - return expf(-(x * x + y * y) / (r * r)); -} - -static int -stepno(float v) -{ - if ((double)v < 1. / 8.) - return 0; - if ((double)v < 3. / 8.) - return 1; - if ((double)v < 7 / 8.) - return 2; - - return 3; -} - -static void -draw_border(WINDOW *w) -{ - wborder(w, 0, 0, 0, 0, 0, 0, 0, 0); -} - -static void -matrix_draw(WINDOW *w, float mat[ROWS][COLS]) -{ - int ch, i, j; - static char steps[] = " .oO"; - - wclear(w); - draw_border(w); - for (i = 0; i < ROWS; i++) { - wmove(w, 1 + i, 1); - for (j = 0; j < COLS; j++) { - ch = steps[stepno(mat[i][j])]; - waddch(w, (const chtype)ch); - } - } - - wnoutrefresh(w); -} - -static void -matrix_compute(vec_t *center, size_t ncenters, float mat[ROWS][COLS]) -{ - int i, j, k; - float radius = 4; - - for (i = 0; i < ROWS; i++) { - for (j = 0; j < COLS; j++) { - mat[i][j] = 0.; - for (k = 0; k < (int)ncenters; k++) { - mat[i][j] += gaussian((float)i - center[k].x, - (float)j - center[k].y, radius); - } - } - } -} - -static void -move_centers(vec_t *center, vec_t *direction, size_t ncenters) -{ - const float steplen = (float).01; - int k; - bool recursed[2] = {false, false}; - - for (k = 0; k < (int)ncenters; k++) { - recursed[k] = false; - step(¢er[k], &direction[k], steplen, &recursed[k]); - } -} - -static void -matrix_open(state_t *s, bool rw) -{ - const char *func; - hid_t fapl, fcpl; - H5F_vfd_swmr_config_t config; - - memset(&config, '\0', sizeof(config)); - - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, SWMR_TICK_LEN, 5, rw, FALSE, 128, "./my_md_file"); - - /* use_latest_format, use_vfd_swmr, only_meta_page, config */ - fapl = vfd_swmr_create_fapl(false, true, true, &config); - if (fapl < 0) { - errx(EXIT_FAILURE, "%s.%d vfd_swmr_create_fapl failed", - __func__, __LINE__); - } - - fcpl = H5Pcreate(H5P_FILE_CREATE); - if (fcpl < 0) { - errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", - __func__, __LINE__); - } - - /* Set file space strategy to paged aggregation in fcpl. - * Page buffering *requires* this strategy. - * - * I set the free-space threshold to 1GB so that deleted - * datasets are not recycled. - */ - if (H5Pset_file_space_strategy(fcpl, - H5F_FSPACE_STRATEGY_PAGE, false, 1024 * 1024 * 1024) < 0) - errx(EXIT_FAILURE, "H5Pset_file_space_strategy failed"); - - if (rw) { - s->file = H5Fcreate("vfd_swmr_gaussians.h5", H5F_ACC_TRUNC, fcpl, fapl); - func = "H5Fcreate"; - } else { - s->file = H5Fopen("vfd_swmr_gaussians.h5", H5F_ACC_RDONLY, fapl); - func = "H5Fopen"; - } - - H5Pclose(fapl); - - if (s->file < 0) - errx(EXIT_FAILURE, "%s failed", func); -} - -static void -fuzz(float mat[ROWS][COLS]) -{ - int i, j; - - for (i = 0; i < ROWS; i++) { - for (j = 0; j < COLS; j++) { - long int temp = random() / RAND_MAX * (long int)(9. / 64.); - mat[i][j] += (float)temp; - } - } -} - -int -main(int argc, char **argv) -{ - char buf[32]; - float mat[ROWS][COLS]; - int frameno; - vec_t center[2] = {{.x = .5, .y = .5}, - {.x = ROWS - .5, .y = COLS - .5}}; - vec_t direction[2] = {{.x = 3, .y = 7}, {.x = 43, .y = 41}}; - struct sigaction osa; - WINDOW *topw = NULL, *w = NULL; - personality_t personality; - state_t s; - uint64_t temp; - - srandom((unsigned int)time(NULL)); - - setlocale(LC_ALL, ""); - - state_init(&s, argc, argv); - - switch (s.progname[0]) { - case 'r': - personality = READ; - break; - case 'w': - personality = WRITE; - break; - default: - personality = STANDALONE; - break; - } - establish_handler(&osa); - - switch (personality) { - case WRITE: - matrix_open(&s, true); - create_group(&s); - create_dataset(&s); - break; - case READ: - matrix_open(&s, false); - open_group(&s); - open_dataset(&s); - break; - default: - break; - } - - if ((topw = initscr()) == NULL) - errx(EXIT_FAILURE, "initscr failed"); - else if ((w = subwin(topw, ROWS + 2, COLS + 2, 0, 0)) == NULL) - errx(EXIT_FAILURE, "subwin failed"); - - for (frameno = 0; unbroken; ) { - struct timespec elapsed, start, stop; - uint64_t elapsed_ns; - clock_gettime(CLOCK_MONOTONIC, &start); - - switch (personality) { - case READ: - matrix_read(&s, &frameno, mat); - break; - case WRITE: - case STANDALONE: - matrix_compute(center, __arraycount(center), mat); - if (s.fuzz) - fuzz(mat); - break; - } - switch (personality) { - case READ: - case STANDALONE: - matrix_draw(w, mat); -#if 0 - wmove(topw, ROWS + 3, 0); - waddstr(topw, "\"Don't cross the streams.\""); -#endif - break; - case WRITE: - matrix_write(&s, frameno, mat); - break; - } - - snprintf(buf, sizeof(buf), "Frame %d.", frameno); - wmove(topw, ROWS + 2, 0); - waddstr(topw, buf); - snprintf(buf, sizeof(buf), "Rate %lld/s.", - 1000000000ULL / timespec2ns(&s.update_interval)); - wmove(topw, ROWS + 2, COLS + 2 - (int)strlen(buf)); - waddstr(topw, buf); - wnoutrefresh(topw); - doupdate(); - - nanosleep(&s.update_interval, NULL); - - switch (personality) { - case STANDALONE: - case WRITE: - move_centers(center, direction, __arraycount(center)); - frameno++; - break; - case READ: - break; - } - clock_gettime(CLOCK_MONOTONIC, &stop); - - timespecsub(&stop, &start, &elapsed); - elapsed_ns = timespec2ns(&elapsed); - - if (elapsed_ns < s.min_elapsed_ns) - s.min_elapsed_ns = elapsed_ns; - if (elapsed_ns > s.max_elapsed_ns) - s.max_elapsed_ns = elapsed_ns; - s.total_elapsed_ns += elapsed_ns; - s.total_loops++; - } - endwin(); - fprintf(stderr, "Iteration stats:\n"); - fprintf(stderr, "min. elapsed %" PRIu64 " ms\n", - s.min_elapsed_ns / 1000000); - fprintf(stderr, "max. elapsed %" PRIu64 " ms\n", - s.max_elapsed_ns / 1000000); - temp = s.total_elapsed_ns / s.total_loops / 1000000; - fprintf(stderr, "avg. elapsed %.3f ms\n", (double)temp); - disestablish_handler(&osa); - return EXIT_SUCCESS; -} -- cgit v0.12 From 65bf098ee6656f67e78cf1a7aa6ec3f81f867e1f Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 20:25:33 -0800 Subject: Adds HD prefix to POSIX calls in src --- src/H5FDvfd_swmr.c | 20 ++++++++++---------- src/H5Fvfd_swmr.c | 18 +++++++++--------- src/H5MFsection.c | 4 ++-- src/H5PB.c | 10 +++++----- src/H5VLnative_object.c | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 898adaf..6f06373 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -477,7 +477,7 @@ H5FD_vfd_swmr_close(H5FD_t *_file) if (file->hdf5_file_lf != NULL) { if (file->hdf5_file_lf->exc_owner != NULL) { - assert(file->hdf5_file_lf->exc_owner == &file->pub); + HDassert(file->hdf5_file_lf->exc_owner == &file->pub); file->hdf5_file_lf->exc_owner = NULL; } @@ -562,7 +562,7 @@ H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl) { H5FD_vfd_swmr_t *self = (H5FD_vfd_swmr_t *)_self; - assert(_self->driver_id == H5FD_VFD_SWMR_g); + HDassert(_self->driver_id == H5FD_VFD_SWMR_g); if (_self->cls == _other->cls) { H5FD_vfd_swmr_t *other = (H5FD_vfd_swmr_t *)_other; @@ -598,7 +598,7 @@ H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl) return NULL; } - equal_configs = memcmp(&self->config, config, sizeof(*config)) == 0; + equal_configs = HDmemcmp(&self->config, config, sizeof(*config)) == 0; free(config); @@ -1263,13 +1263,13 @@ H5FD__vfd_swmr_header_deserialize(H5FD_vfd_swmr_t *file, FUNC_ENTER_STATIC /* Set file pointer to the beginning the file */ - if (lseek(file->md_fd, H5FD_MD_HEADER_OFF, SEEK_SET) < 0) { + if (HDlseek(file->md_fd, H5FD_MD_HEADER_OFF, SEEK_SET) < 0) { HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, \ "unable to seek in metadata file"); } /* Read the header */ - nread = read(file->md_fd, image, H5FD_MD_HEADER_SIZE); + nread = HDread(file->md_fd, image, H5FD_MD_HEADER_SIZE); /* Try again if a signal interrupted the read. */ if (nread == -1 && errno == EINTR) @@ -1287,7 +1287,7 @@ H5FD__vfd_swmr_header_deserialize(H5FD_vfd_swmr_t *file, HGOTO_DONE(FALSE); /* Verify magic number */ - if (memcmp(image, H5FD_MD_HEADER_MAGIC, H5_SIZEOF_MAGIC) != 0) + if (HDmemcmp(image, H5FD_MD_HEADER_MAGIC, H5_SIZEOF_MAGIC) != 0) HGOTO_DONE(FALSE); /* Verify stored and computed checksums are equal */ @@ -1371,12 +1371,12 @@ H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, } /* We may seek past EOF. That's ok, the read(2) will catch that. */ - if (lseek(file->md_fd, (HDoff_t)md_header->index_offset, SEEK_SET) < 0){ + if (HDlseek(file->md_fd, (HDoff_t)md_header->index_offset, SEEK_SET) < 0){ HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file"); } - nread = read(file->md_fd, image, md_header->index_length); + nread = HDread(file->md_fd, image, md_header->index_length); /* Try again if a signal interrupted the read. */ if (nread == -1 && errno == EINTR) @@ -1423,7 +1423,7 @@ H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, * read bad magic. It's possible to recover by * re-reading the header. */ - if (memcmp(image, H5FD_MD_INDEX_MAGIC, H5_SIZEOF_MAGIC) != 0) + if (HDmemcmp(image, H5FD_MD_INDEX_MAGIC, H5_SIZEOF_MAGIC) != 0) HGOTO_DONE(FALSE); /* Verify stored and computed checksums are equal */ @@ -1521,7 +1521,7 @@ H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t reload_hdr_and_index, H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ herr_t ret_value = SUCCEED; /* Return value */ - assert(index == NULL || num_entries_ptr != NULL); + HDassert(index == NULL || num_entries_ptr != NULL); FUNC_ENTER_NOAPI(FAIL) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 555619d..5e11073 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -183,7 +183,7 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) md_size = (hsize_t)shared->vfd_swmr_config.md_pages_reserved * shared->fs_page_size; - assert(shared->fs_page_size >= H5FD_MD_HEADER_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){ @@ -246,7 +246,7 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) HGOTO_ERROR(H5E_FILE, H5E_CANTLOAD, FAIL, "unable to load/decode metadata file"); - assert(shared->tick_num != 0); + HDassert(shared->tick_num != 0); vfd_swmr_reader_did_increase_tick_to(shared->tick_num); hlog_fast(tick, "%s first tick %" PRIu64, @@ -349,7 +349,7 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) } hlog_fast(shadow_defrees, "Emptied deferred shadow frees."); - assert(TAILQ_EMPTY(&shared->shadow_defrees)); + HDassert(TAILQ_EMPTY(&shared->shadow_defrees)); } else { /* For file flush */ /* Update end_of_tick */ if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, TRUE) < 0) @@ -441,7 +441,7 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, HDqsort(index, num_entries, sizeof(*index), H5F__idx_entry_cmp); /* Assert that no HDF5 page offsets are duplicated. */ for (i = 1; i < num_entries; i++) - assert(index[i - 1].hdf5_page_offset < index[i].hdf5_page_offset); + HDassert(index[i - 1].hdf5_page_offset < index[i].hdf5_page_offset); } /* For each non-null entry_ptr in the index: @@ -749,8 +749,8 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, if (ie->clean && ie->tick_of_last_flush + max_lag < tick_num) { - assert(!ie->garbage); - assert(ie->entry_ptr == NULL); + HDassert(!ie->garbage); + HDassert(ie->entry_ptr == NULL); hlog_fast(shadow_index_reclaim, "Reclaiming shadow index slot %" PRIu32 @@ -1142,7 +1142,7 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) /* This is ok if we're entering the API, but it should * not happen if we're exiting the API. */ - assert(entering_api || tmp_tick_num < + HDassert(entering_api || tmp_tick_num < shared->tick_num + shared->vfd_swmr_config.max_lag); if (!entering_api) { @@ -1244,7 +1244,7 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) * case where the new entry is *longer*, because the * extension could overlap with a second entry. */ - assert(oent->length == nent->length); + HDassert(oent->length == nent->length); hlog_fast(shadow_index_update, "shadow page for slot %" PRIu32 " lower page %" PRIu64 @@ -1447,7 +1447,7 @@ H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *entry) entry->tick_num, (intmax_t)entry->end_of_tick.tv_sec, entry->end_of_tick.tv_nsec); - assert(entry->vfd_swmr_writer == shared->vfd_swmr_writer); + HDassert(entry->vfd_swmr_writer == shared->vfd_swmr_writer); entry->tick_num = shared->tick_num; entry->end_of_tick = shared->end_of_tick; diff --git a/src/H5MFsection.c b/src/H5MFsection.c index 1b9e756..6d23748 100644 --- a/src/H5MFsection.c +++ b/src/H5MFsection.c @@ -829,10 +829,10 @@ H5MF__sect_large_can_merge(const H5FS_section_info_t *_sect1, HDassert(sect2); HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */ if (!H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr)) { - fprintf(stderr, "%s.%d: sect1->sect_info.addr %" PRIuHADDR + HDfprintf(stderr, "%s.%d: sect1->sect_info.addr %" PRIuHADDR ", sect2->sect_info.addr %" PRIuHADDR "\n", __func__, __LINE__, sect1->sect_info.addr, sect2->sect_info.addr); - fprintf(stderr, "%s.%d: sect1->sect_info.size %" PRIuHSIZE + HDfprintf(stderr, "%s.%d: sect1->sect_info.size %" PRIuHSIZE ", sect2->sect_info.size %" PRIuHSIZE "\n", __func__, __LINE__, sect1->sect_info.size, sect2->sect_info.size); HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't merge") diff --git a/src/H5PB.c b/src/H5PB.c index d20be7b..c98b094 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -1515,7 +1515,7 @@ shadow_idx_entry_remove(H5F_shared_t *shared, uint64_t page, bool only_mark) if (shared->mdf_idx_entries_used > i + 1) { const size_t ntocopy = (size_t)(shared->mdf_idx_entries_used - (i + 1)); - memmove(&shared->mdf_idx[i], + HDmemmove(&shared->mdf_idx[i], &shared->mdf_idx[i + 1], ntocopy * sizeof(shared->mdf_idx[i + 1])); } @@ -1629,7 +1629,7 @@ H5PB_remove_entry(H5F_shared_t *shared, haddr_t addr) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, "forced eviction failed") - assert(!shared->vfd_swmr_writer || vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page, false) == NULL); + HDassert(!shared->vfd_swmr_writer || vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page, false) == NULL); } done: @@ -2266,7 +2266,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, "\n\nmax mdf index len (%" PRIu32 ") exceeded.\n\n", shared->mdf_idx_len); HDfprintf(stderr, "tick = %" PRIu64 ".\n", tick_num); - exit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } ie_ptr = idx + new_index_entry_index; @@ -2305,7 +2305,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, ie_ptr->entry_ptr = entry->image_ptr; ie_ptr->tick_of_last_change = tick_num; - assert(entry->is_dirty); + HDassert(entry->is_dirty); ie_ptr->clean = false; ie_ptr->tick_of_last_flush = 0; } @@ -4725,7 +4725,7 @@ H5PB__write_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, for (iter_page = page + 1; iter_page < last_page; iter_page++) { H5PB__SEARCH_INDEX(pb_ptr, iter_page, overlap, FAIL) - assert(overlap == NULL); + HDassert(overlap == NULL); } if (new_image == NULL) { HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index 8f60ac4..4fdc0b0 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -342,7 +342,7 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5V /* Lookup object */ case H5VL_OBJECT_LOOKUP: { - H5O_token_t *token = va_arg(arguments, H5O_token_t *); + H5O_token_t *token = HDva_arg(arguments, H5O_token_t *); HDassert(token); -- cgit v0.12 From 46865e70afd268308059ab1d8b0e86e9b8de92f4 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Mon, 1 Mar 2021 20:32:15 -0800 Subject: Switches H5MF memory calls to use H5MM --- src/H5MF.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/H5MF.c b/src/H5MF.c index 22438d3..e3600ed 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -150,7 +150,7 @@ defer_free(H5F_shared_t *shared, H5FD_mem_t alloc_type, haddr_t addr, { lower_defree_t *df; - if ((df = malloc(sizeof(*df))) == NULL) + if ((df = H5MM_malloc(sizeof(*df))) == NULL) return FAIL; df->alloc_type = alloc_type; @@ -204,7 +204,7 @@ H5MF_process_deferred_frees(H5F_t *f, const uint64_t tick_num) SIMPLEQ_REMOVE_HEAD(&defrees, link); if (H5MF__xfree_impl(f, df->alloc_type, df->addr, df->size) < 0) err = FAIL; - free(df); + H5MM_xfree(df); } if (err != SUCCEED) { -- cgit v0.12 From cd3011edad528050f4f822b4b237d2fe1209f829 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 01:40:05 -0800 Subject: H5MF.c cleanup * Removes hlog code * Mostly meets THG coding standards now * Still needs commenting and probably another tidying pass --- src/H5MF.c | 148 +++++++++++-------------------------------------------------- 1 file changed, 25 insertions(+), 123 deletions(-) diff --git a/src/H5MF.c b/src/H5MF.c index e3600ed..5ba7284 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -22,9 +22,6 @@ *------------------------------------------------------------------------- */ -#include "H5queue.h" -#include "hlog.h" - /****************/ /* Module Setup */ /****************/ @@ -46,8 +43,6 @@ #include "H5VMprivate.h" /* Vectors and arrays */ -#include "hlog.h" - /****************/ /* Local Macros */ /****************/ @@ -118,6 +113,9 @@ static herr_t H5MF__close_delete_fstype(H5F_t *f, H5F_mem_page_t type); /* Callbacks */ static herr_t H5MF__sects_cb(H5FS_section_info_t *_sect, void *_udata); +/* VFD SWMR */ +static herr_t H5MF__defer_free(H5F_shared_t *shared, H5FD_mem_t alloc_type, + haddr_t addr, hsize_t size); /*********************/ /* Package Variables */ @@ -135,58 +133,38 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Local Variables */ /*******************/ -HLOG_OUTLET_DECL(h5mf); -HLOG_OUTLET_SHORT_DEFN(h5mf, all); -HLOG_OUTLET_SHORT_DEFN(h5mf_defer, h5mf); -HLOG_OUTLET_SHORT_DEFN(h5mf_free, h5mf); -HLOG_OUTLET_SHORT_DEFN(h5mf_alloc, h5mf); -HLOG_OUTLET_MEDIUM_DEFN(noisy_h5mf_alloc, h5mf_alloc, HLOG_OUTLET_S_OFF); -HLOG_OUTLET_SHORT_DEFN(h5mf_extend, h5mf); -HLOG_OUTLET_SHORT_DEFN(h5mf_shrink, h5mf); - static herr_t -defer_free(H5F_shared_t *shared, H5FD_mem_t alloc_type, haddr_t addr, +H5MF__defer_free(H5F_shared_t *shared, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) { - lower_defree_t *df; + lower_defree_t *df = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC if ((df = H5MM_malloc(sizeof(*df))) == NULL) - return FAIL; + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to allocate buffer") df->alloc_type = alloc_type; df->addr = addr; df->size = size; df->free_after_tick = shared->tick_num + shared->vfd_swmr_config.max_lag; - hlog_fast(h5mf_defer, - "%s.%d: deferred free at %" PRIuHADDR ", %" PRIuHSIZE - " bytes until tick %" PRIu64, __FILE__, __LINE__, addr, size, - df->free_after_tick); - SIMPLEQ_INSERT_TAIL(&shared->lower_defrees, df, link); - return SUCCEED; -} - -static uint64_t -H5MF_total_deferred_frees(H5F_shared_t *shared) -{ - lower_defree_t *df; - uint64_t total = 0; - - SIMPLEQ_FOREACH(df, &shared->lower_defrees, link) - total += df->size; - - return total; -} +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MF__defer_free() */ herr_t H5MF_process_deferred_frees(H5F_t *f, const uint64_t tick_num) { lower_defree_t *df; - herr_t err = SUCCEED; H5F_shared_t *shared = f->shared; lower_defree_queue_t defrees = SIMPLEQ_HEAD_INITIALIZER(defrees); + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOERR /* Have to empty the queue before processing it because we * could re-enter this routine through H5MF__xfree_impl. If @@ -198,25 +176,19 @@ H5MF_process_deferred_frees(H5F_t *f, const uint64_t tick_num) while ((df = SIMPLEQ_FIRST(&defrees)) != NULL) { if (tick_num <= df->free_after_tick) break; - hlog_fast(h5mf_defer, - "%s.%d: processing free at %" PRIuHADDR ", %" PRIuHSIZE " bytes", - __FILE__, __LINE__, df->addr, df->size); SIMPLEQ_REMOVE_HEAD(&defrees, link); + + /* Record errors here, but keep trying to free */ if (H5MF__xfree_impl(f, df->alloc_type, df->addr, df->size) < 0) - err = FAIL; + ret_value = FAIL; H5MM_xfree(df); } - if (err != SUCCEED) { - hlog_fast(h5mf_defer, "%s.%d: error: dropped entries on the floor", - __FILE__, __LINE__); - } - - /* Save remaining entries for processing, later. */ + /* Save remaining entries for processing, later */ SIMPLEQ_CONCAT(&shared->lower_defrees, &defrees); - return err; -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MF_process_deferred_frees() */ /*------------------------------------------------------------------------- @@ -883,11 +855,6 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, HADDR_UNDEF) - hlog_fast(h5mf_alloc, - "%s: enter %p type %u size %" PRIuHSIZE " tick %" PRIu64, - __func__, (void *)f->shared, (unsigned)alloc_type, size, - f->shared->vfd_swmr_writer ? f->shared->tick_num : 0); - /* check arguments */ HDassert(f); HDassert(f->shared); @@ -902,8 +869,6 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) } H5MF__alloc_to_fs_type(f->shared, alloc_type, size, &fs_type); - hlog_fast(noisy_h5mf_alloc, "%s: Check 1.0", __func__); - /* Set the ring type in the API context */ if(H5MF__fsm_type_is_self_referential(f->shared, fs_type)) fsm_ring = H5AC_RING_MDFSM; @@ -937,8 +902,6 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) /* If no space is found from the free-space manager, continue further action */ if(!H5F_addr_defined(ret_value)) { - hlog_fast(noisy_h5mf_alloc, "%s: Check 2.0", __func__); - if(f->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE) { HDassert(f->shared->fs_page_size >= H5F_FILE_SPACE_PAGE_SIZE_MIN); if(HADDR_UNDEF == (ret_value = H5MF__alloc_pagefs(f, alloc_type, size))) @@ -951,16 +914,11 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) } /* end if */ HDassert(H5F_addr_defined(ret_value)); - hlog_fast(noisy_h5mf_alloc, "%s: Check 3.0", FUNC); - done: /* Reset the ring in the API context */ if(orig_ring != H5AC_RING_INV) H5AC_set_ring(orig_ring, NULL); - hlog_fast(h5mf_alloc, - "%s: leave %p type %u addr %" PRIuHADDR " size %" PRIuHSIZE, - __func__, (void *)f->shared, (unsigned)alloc_type, ret_value, size); #ifdef H5MF_ALLOC_DEBUG_DUMP H5MF__sects_dump(f, stderr); #endif /* H5MF_ALLOC_DEBUG_DUMP */ @@ -1190,12 +1148,7 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) - hlog_fast(h5mf_free, "%s: Entering - alloc_type %u addr %" PRIuHADDR - " size %" PRIuHSIZE " tick %" PRIu64, - __func__, (unsigned)alloc_type, addr, size, - f->shared->vfd_swmr_writer ? f->shared->tick_num : 0); - - /* check arguments */ + /* Check arguments */ HDassert(f); if(!H5F_addr_defined(addr) || 0 == size) HGOTO_DONE(SUCCEED) @@ -1207,7 +1160,7 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) * file starts to close. */ ret_value = H5MF__xfree_impl(f, alloc_type, addr, size); - } else if (defer_free(f->shared, alloc_type, addr, size) < 0) + } else if (H5MF__defer_free(f->shared, alloc_type, addr, size) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "could not defer") else if (H5MF_process_deferred_frees(f, f->shared->tick_num) < 0) { HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGC, FAIL, @@ -1228,10 +1181,6 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si H5AC_ring_t fsm_ring; /* Ring of FSM */ herr_t ret_value = SUCCEED; /* Return value */ - hlog_fast(h5mf_free, - "%s: enter %p type %u addr %" PRIuHADDR " size %" PRIuHSIZE, - __func__, (void *)f->shared, (unsigned)alloc_type, addr, size); - FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG) H5MF__alloc_to_fs_type(f->shared, alloc_type, size, &fs_type); @@ -1272,25 +1221,16 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si * space is at the end of the file */ - hlog_fast(h5mf_free, "%s: fs_addr %" PRIuHADDR, __func__, - f->shared->fs_addr[fs_type]); - if(!H5F_addr_defined(f->shared->fs_addr[fs_type])) { htri_t status; /* "can absorb" status for section into */ - hlog_fast(h5mf_free, "%s: Trying to avoid starting up free space manager", __func__); - /* Try to shrink the file or absorb the block into a block aggregator */ if((status = H5MF_try_shrink(f, alloc_type, addr, size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't check for absorbing block") else if(status > 0) HGOTO_DONE(SUCCEED) - else if(size < f->shared->fs_threshold) { - hlog_fast(h5mf_free, "%s: dropping addr %" PRIuHADDR - " size %" PRIuHSIZE " on the floor!", - __func__, addr, size); - HGOTO_DONE(SUCCEED) - } + else if(size < f->shared->fs_threshold) + HGOTO_DONE(SUCCEED) } /* If we are deleting the free space manager, leave now, to avoid @@ -1304,8 +1244,6 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si */ if(f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING || !H5F_HAVE_FREE_SPACE_MANAGER(f)) { - hlog_fast(h5mf_free, "%s: dropping addr %" PRIuHADDR - " size %" PRIuHSIZE " on the floor!", __func__, addr, size); HGOTO_DONE(SUCCEED) } @@ -1326,14 +1264,11 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si if(size >= f->shared->fs_threshold) { HDassert(f->shared->fs_man[fs_type]); - hlog_fast(h5mf_free, "%s: Before H5FS_sect_add()", __func__); - /* Add to the free space for the file */ if(H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space") node = NULL; - hlog_fast(h5mf_free, "%s: After H5FS_sect_add()", __func__); } else { htri_t merged; /* Whether node was merged */ H5MF_sect_ud_t udata; /* User data for callback */ @@ -1362,9 +1297,6 @@ done: if(H5MF__sect_free((H5FS_section_info_t *)node) < 0) HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node") - hlog_fast(h5mf_free, - "%s: %p leave %d", __func__, (void *)f->shared, ret_value); - #ifdef H5MF_ALLOC_DEBUG_DUMP H5MF__sects_dump(f, stderr); #endif /* H5MF_ALLOC_DEBUG_DUMP */ @@ -1460,10 +1392,6 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) - hlog_fast(h5mf_extend, "%s: Entering: alloc_type %u addr %" PRIuHADDR - " size %" PRIuHSIZE " extra_requested %" PRIuHSIZE, __func__, - (unsigned)alloc_type, addr, size, extra_requested); - /* Sanity check */ HDassert(f); HDassert(H5F_INTENT(f) & H5F_ACC_RDWR); @@ -1511,9 +1439,6 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, if((ret_value = H5F__try_extend(f, map_type, end, extra_requested + frag_size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending file") - hlog_fast(h5mf_extend, "%s: extended %s", __func__, - htri_to_string(ret_value)); - /* If extending at EOA succeeds: */ /* for paged aggregation, put the fragment into the large-sized free-space manager */ if(ret_value == TRUE && H5F_PAGED_AGGR(f) && frag_size) { @@ -1547,9 +1472,6 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, aggr = (map_type == H5FD_MEM_DRAW) ? &(f->shared->sdata_aggr) : &(f->shared->meta_aggr); if((ret_value = H5MF__aggr_try_extend(f, aggr, map_type, end, extra_requested)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending aggregation block") - - hlog_fast(h5mf_extend, "%s: H5MF__aggr_try_extend %s", __func__, - htri_to_string(ret_value)); } /* If no extension so far, try to extend into a free-space section */ @@ -1572,8 +1494,6 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, if((ret_value = H5FS_sect_try_extend(f, f->shared->fs_man[fs_type], addr, size, extra_requested, H5FS_ADD_RETURNED_SPACE, &udata)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending block in free space manager") - hlog_fast(h5mf_extend, "%s: Try to H5FS_sect_try_extend %s", - __func__, htri_to_string(ret_value)); } /* For paged aggregation and a metadata block: try to extend into page end threshold */ @@ -1582,8 +1502,6 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, if(frag_size <= H5F_PGEND_META_THRES(f) && extra_requested <= frag_size) ret_value = TRUE; - - hlog_fast(h5mf_extend, "%s: Try to extend into the page end threshold %s", __func__, htri_to_string(ret_value)); } } } @@ -1593,9 +1511,6 @@ done: if(orig_ring != H5AC_RING_INV) H5AC_set_ring(orig_ring, NULL); - - hlog_fast(h5mf_extend, "%s: Leaving: ret_value %s", __func__, htri_to_string(ret_value)); - #ifdef H5MF_ALLOC_DEBUG_DUMP H5MF__sects_dump(f, stderr); #endif /* H5MF_ALLOC_DEBUG_DUMP */ @@ -1631,9 +1546,6 @@ H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) - hlog_fast(h5mf_shrink, "%s: Entering - alloc_type %u addr %" PRIuHADDR - " size %" PRIuHSIZE, __func__, (unsigned)alloc_type, addr, size); - /* check arguments */ HDassert(f); HDassert(f->shared); @@ -1686,9 +1598,6 @@ done: if(node && H5MF__sect_free((H5FS_section_info_t *)node) < 0) HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node") - hlog_fast(h5mf_shrink, "%s: Leaving, ret_value %d", __func__, - ret_value); - FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5MF_try_shrink() */ @@ -1712,15 +1621,10 @@ H5MF_close(H5F_t *f) FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) - hlog_fast(h5mf, "%s: entering", __func__); - /* check args */ HDassert(f); HDassert(f->shared); - hlog_fast(h5mf, "%s: total deferred frees %" PRIu64, __func__, - H5MF_total_deferred_frees(f->shared)); - if(H5F_PAGED_AGGR(f)) { if((ret_value = H5MF__close_pagefs(f)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't close free-space managers for 'page' file space") @@ -1730,8 +1634,6 @@ H5MF_close(H5F_t *f) } /* end else */ done: - hlog_fast(h5mf, "%s: leaving", __func__); - FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5MF_close() */ -- cgit v0.12 From 4173c4b0b9152197562ad227a66137091cba9884 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 02:13:31 -0800 Subject: Switches H5FDvfd_swmr.c memory calls to use H5MM --- src/H5FDvfd_swmr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 6f06373..6e29376 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -276,7 +276,7 @@ H5FD__swmr_reader_open(H5FD_vfd_swmr_t *file) file->api_elapsed_nbuckets = file->config.max_lag + 1; file->api_elapsed_ticks = - calloc(file->api_elapsed_nbuckets, sizeof(*file->api_elapsed_ticks)); + H5MM_calloc(file->api_elapsed_nbuckets * sizeof(*file->api_elapsed_ticks)); if (file->api_elapsed_ticks == NULL) { HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, @@ -437,7 +437,7 @@ swmr_reader_close(H5FD_vfd_swmr_t *file) "%s: %" PRIu32 " ticks elapsed in API %" PRIu64 " times", __func__, i, file->api_elapsed_ticks[i]); } - free(file->api_elapsed_ticks); + H5MM_xfree(file->api_elapsed_ticks); } /* Close the metadata file */ @@ -589,7 +589,7 @@ H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl) return NULL; } - if ((config = malloc(sizeof(*config))) == NULL) { + if ((config = H5MM_malloc(sizeof(*config))) == NULL) { HERROR(H5E_ARGS, H5E_BADTYPE, "could not allocate config"); return NULL; } @@ -600,7 +600,7 @@ H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl) equal_configs = HDmemcmp(&self->config, config, sizeof(*config)) == 0; - free(config); + H5MM_xfree(config); if (equal_configs) return _self; -- cgit v0.12 From 7b603397c3a5f604da2ef8cdc3cab0eb27780a34 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 02:29:01 -0800 Subject: Switches memcpy to H5MM_memcpy in H5Fvfd_swmr.c --- 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 5e11073..fafff01 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1984,7 +1984,7 @@ vfd_swmr_enlarge_shadow_index(H5F_t *f) * process of adding entries, and some callers may not update * _entries_used immediately. */ - memcpy(new_mdf_idx, old_mdf_idx, sizeof(new_mdf_idx[0]) * old_mdf_idx_len); + H5MM_memcpy(new_mdf_idx, old_mdf_idx, sizeof(new_mdf_idx[0]) * old_mdf_idx_len); shared->writer_index_offset = idx_addr; ret_value = shared->mdf_idx = new_mdf_idx; -- cgit v0.12 From eea7c11b6acd1d193046736466be73beaf8f8faa Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 02:39:36 -0800 Subject: Fix unfreed memory after fork in vfd_swmr test The writer configuration in the vfd_swmr test was not freed in the child process after a call to fork() causing a memory leak. --- test/vfd_swmr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index d49629f..b140813 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -1237,6 +1237,10 @@ test_reader_md_concur(void) if(HDclose(child_pfd[0]) < 0) HDexit(EXIT_FAILURE); + /* Free unused configuration */ + if(config_writer) + HDfree(config_writer); + /* * Case A: reader * --verify an empty index @@ -2167,6 +2171,10 @@ test_disable_enable_eot_concur(void) if(HDclose(child_pfd[0]) < 0) HDexit(EXIT_FAILURE); + /* Free unused configuration */ + if(config_writer) + HDfree(config_writer); + /* * Open the file 3 times as VFD SWMR reader * Enable and disable EOT for a file @@ -2440,6 +2448,10 @@ test_file_end_tick_concur(void) if(HDclose(child_pfd[0]) < 0) HDexit(EXIT_FAILURE); + /* Free unused configuration */ + if(config_writer) + HDfree(config_writer); + /* * Open the file 3 times as VFD SWMR reader * Trigger EOT for the files -- cgit v0.12 From 6639693cff48bb16bddb05121a73c063c9f92ca2 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 02:51:55 -0800 Subject: Removed most C library include lines from tests --- test/vfd_swmr_addrem_writer.c | 1 - test/vfd_swmr_bigset_writer.c | 2 -- test/vfd_swmr_common.h | 1 - test/vfd_swmr_group_writer.c | 2 -- test/vfd_swmr_remove_reader.c | 1 - test/vfd_swmr_vlstr_reader.c | 2 -- test/vfd_swmr_vlstr_writer.c | 2 -- test/vfd_swmr_zoo_writer.c | 2 -- 8 files changed, 13 deletions(-) diff --git a/test/vfd_swmr_addrem_writer.c b/test/vfd_swmr_addrem_writer.c index ad651e6..b4c0e1f 100644 --- a/test/vfd_swmr_addrem_writer.c +++ b/test/vfd_swmr_addrem_writer.c @@ -33,7 +33,6 @@ /***********/ #include /* errx(3) */ -#include /* EXIT_FAILURE */ #include "h5test.h" #include "vfd_swmr_common.h" diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index d57479a..4bf08fd 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -68,8 +68,6 @@ #include #include -#include /* nanosleep(2) */ -#include /* getopt(3) */ #define H5C_FRIEND /*suppress error about including H5Cpkg */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index a4bf50e..761a706 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -18,7 +18,6 @@ /* Headers */ /***********/ -#include #include "h5test.h" /**********/ diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index ede4594..155e9b1 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -13,8 +13,6 @@ #include #include -#include /* nanosleep(2) */ -#include /* getopt(3) */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ diff --git a/test/vfd_swmr_remove_reader.c b/test/vfd_swmr_remove_reader.c index c4eaba2..80fe042 100644 --- a/test/vfd_swmr_remove_reader.c +++ b/test/vfd_swmr_remove_reader.c @@ -28,7 +28,6 @@ /***********/ #include /* errx(3) */ -#include /* EXIT_FAILURE */ #include "h5test.h" #include "vfd_swmr_common.h" diff --git a/test/vfd_swmr_vlstr_reader.c b/test/vfd_swmr_vlstr_reader.c index e75af35..c6bf1dc 100644 --- a/test/vfd_swmr_vlstr_reader.c +++ b/test/vfd_swmr_vlstr_reader.c @@ -12,8 +12,6 @@ */ #include -#include /* nanosleep(2) */ -#include /* getopt(3) */ #define H5C_FRIEND /*suppress error about including H5Cpkg */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ diff --git a/test/vfd_swmr_vlstr_writer.c b/test/vfd_swmr_vlstr_writer.c index 17e7d83..3085575 100644 --- a/test/vfd_swmr_vlstr_writer.c +++ b/test/vfd_swmr_vlstr_writer.c @@ -12,8 +12,6 @@ */ #include -#include /* nanosleep(2) */ -#include /* getopt(3) */ #define H5C_FRIEND /*suppress error about including H5Cpkg */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c index c98b2e1..901e1cb 100644 --- a/test/vfd_swmr_zoo_writer.c +++ b/test/vfd_swmr_zoo_writer.c @@ -13,8 +13,6 @@ #include #include /* basename(3) */ -#include /* nanosleep(2) */ -#include /* getopt(3) */ #define H5C_FRIEND /* suppress error about including H5Cpkg */ #define H5F_FRIEND /* suppress error about including H5Fpkg */ -- cgit v0.12 From f1bc0c97a93b84ef429b2240e4ae8466029ed4db Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 03:22:50 -0800 Subject: Makes libgen.h functions ready for implementation on Windows --- config/cmake/H5pubconf.h.in | 3 +++ config/cmake_ext_mod/ConfigureChecks.cmake | 1 + configure.ac | 2 +- src/H5private.h | 13 +++++++++++++ test/page_buffer.c | 5 ++--- test/vfd_swmr_bigset_writer.c | 3 +-- test/vfd_swmr_group_writer.c | 3 +-- test/vfd_swmr_zoo_writer.c | 4 +--- tools/lib/h5tools.c | 2 -- 9 files changed, 23 insertions(+), 13 deletions(-) diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 64b4852..56cc264 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -222,6 +222,9 @@ /* Define to 1 if you have the `dmalloc' library (-ldmalloc). */ #cmakedefine H5_HAVE_LIBDMALLOC @H5_HAVE_LIBDMALLOC@ +/* Define to 1 if you have the header file. */ +#cmakedefine H5_HAVE_LIBGEN_H @H5_HAVE_LIBGEN_H@ + /* Proceed to build with libhdfs */ #cmakedefine H5_HAVE_LIBHDFS @H5_HAVE_LIBHDFS@ diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake index 0ddb6d0..3a4f711 100644 --- a/config/cmake_ext_mod/ConfigureChecks.cmake +++ b/config/cmake_ext_mod/ConfigureChecks.cmake @@ -136,6 +136,7 @@ CHECK_INCLUDE_FILE_CONCAT ("setjmp.h" ${HDF_PREFIX}_HAVE_SETJMP_H) CHECK_INCLUDE_FILE_CONCAT ("stddef.h" ${HDF_PREFIX}_HAVE_STDDEF_H) CHECK_INCLUDE_FILE_CONCAT ("stdint.h" ${HDF_PREFIX}_HAVE_STDINT_H) CHECK_INCLUDE_FILE_CONCAT ("unistd.h" ${HDF_PREFIX}_HAVE_UNISTD_H) +CHECK_INCLUDE_FILE_CONCAT ("libgen.h" ${HDF_PREFIX}_HAVE_LIBGEN_H) # Windows CHECK_INCLUDE_FILE_CONCAT ("io.h" ${HDF_PREFIX}_HAVE_IO_H) diff --git a/configure.ac b/configure.ac index 6d869f9..bb5561e 100644 --- a/configure.ac +++ b/configure.ac @@ -1144,7 +1144,7 @@ AC_HEADER_TIME AC_CHECK_HEADERS([sys/resource.h sys/time.h unistd.h sys/ioctl.h sys/stat.h]) AC_CHECK_HEADERS([sys/socket.h sys/types.h sys/file.h]) AC_CHECK_HEADERS([stddef.h setjmp.h features.h]) -AC_CHECK_HEADERS([dirent.h]) +AC_CHECK_HEADERS([dirent.h libgen.h]) AC_CHECK_HEADERS([stdint.h], [C9x=yes]) AC_CHECK_HEADERS([stdbool.h]) AC_CHECK_HEADERS([netdb.h netinet/in.h arpa/inet.h]) diff --git a/src/H5private.h b/src/H5private.h index 3e11b4f..6479032 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -154,6 +154,13 @@ #endif /* + * Needed for dirname and basename on POSIX systems + */ +#ifdef H5_HAVE_LIBGEN_H +#include +#endif + +/* * Dynamic library handling. These are needed for dynamically loading I/O * filters and VFDs. */ @@ -727,6 +734,9 @@ typedef struct { #ifndef HDatoll #define HDatoll(S) atoll(S) #endif /* HDatol */ +#ifndef HDbasename + #define HDbasename(P) basename(P) +#endif /* HDbasename */ #ifndef HDbind #define HDbind(A,B,C) bind((A),(B),(C)) /* mirror VFD */ #endif /* HDbind */ @@ -803,6 +813,9 @@ typedef struct { #define HDdifftime(X,Y) ((double)(X)-(double)(Y)) #endif /* H5_HAVE_DIFFTIME */ #endif /* HDdifftime */ +#ifndef HDdirname + #define HDdirname(P) dirname(P) +#endif /* HDdirname */ #ifndef HDdiv #define HDdiv(X,Y) div(X,Y) #endif /* HDdiv */ diff --git a/test/page_buffer.c b/test/page_buffer.c index 88b3317..112ea77 100644 --- a/test/page_buffer.c +++ b/test/page_buffer.c @@ -20,7 +20,6 @@ *************************************************************/ #include -#include #include "h5test.h" @@ -151,8 +150,8 @@ swmr_fapl_augment(hid_t fapl, const char *filename, uint32_t max_lag) HDfprintf(stderr, "temporary string allocation failed\n"); return -1; } - dname = dirname(tname[0]); - bname = basename(tname[1]); + dname = HDdirname(tname[0]); + bname = HDbasename(tname[1]); snprintf(config.md_file_path, sizeof(config.md_file_path), "%s/%s.shadow", dname, bname); free(tname[0]); diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 4bf08fd..7b0f451 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -67,7 +67,6 @@ */ #include -#include #define H5C_FRIEND /*suppress error about including H5Cpkg */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -271,7 +270,7 @@ state_init(state_t *s, int argc, char **argv) *s = state_initializer(); esnprintf(tfile, sizeof(tfile), "%s", argv[0]); - esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile)); + esnprintf(s->progname, sizeof(s->progname), "%s", HDbasename(tfile)); while ((ch = getopt(argc, argv, "FMSVWa:bc:d:n:qr:s:u:")) != -1) { switch (ch) { diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index 155e9b1..2f355c2 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -12,7 +12,6 @@ */ #include -#include #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -85,7 +84,7 @@ state_init(state_t *s, int argc, char **argv) *s = ALL_HID_INITIALIZER; esnprintf(tfile, sizeof(tfile), "%s", argv[0]); - esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile)); + esnprintf(s->progname, sizeof(s->progname), "%s", HDbasename(tfile)); while ((ch = getopt(argc, argv, "SWa:bn:qu:")) != -1) { switch (ch) { diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c index 901e1cb..1792a93 100644 --- a/test/vfd_swmr_zoo_writer.c +++ b/test/vfd_swmr_zoo_writer.c @@ -12,7 +12,6 @@ */ #include -#include /* basename(3) */ #define H5C_FRIEND /* suppress error about including H5Cpkg */ #define H5F_FRIEND /* suppress error about including H5Fpkg */ @@ -23,7 +22,6 @@ #include "H5retry_private.h" #include "H5Cpkg.h" #include "H5Fpkg.h" -// #include "H5Iprivate.h" #include "H5HGprivate.h" #include "H5VLprivate.h" @@ -225,7 +223,7 @@ main(int argc, char **argv) const char *seedvar = "H5_ZOO_STEP_SEED"; bool use_vfd_swmr = true; bool print_estack = false; - const char *progname = basename(argv[0]); + const char *progname = HDbasename(argv[0]); const char *personality = strstr(progname, "vfd_swmr_zoo_"); estack_state_t es; char step = 'b'; diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index e6df7c8..f68eb3b 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -16,8 +16,6 @@ * amongst the various HDF5 tools. */ -#include - #include "h5tools.h" #include "h5tools_dump.h" #include "h5tools_ref.h" -- cgit v0.12 From 6661b21e9a948aa7790be13409f5b3e69c2ebbc9 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 04:07:31 -0800 Subject: Stripped hlog code from H5MV.c --- src/H5MV.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/H5MV.c b/src/H5MV.c index 5b73b9a..66d60b4 100644 --- a/src/H5MV.c +++ b/src/H5MV.c @@ -40,7 +40,6 @@ #include "H5MVpkg.h" /* File memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ -#include "hlog.h" /****************/ /* Local Macros */ @@ -96,8 +95,6 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Local Variables */ /*******************/ -HLOG_OUTLET_SHORT_DEFN(h5mv, all); - /*------------------------------------------------------------------------- * Function: H5MV__create() @@ -283,7 +280,6 @@ H5MV_alloc(H5F_t *f, hsize_t size) haddr_t ret_value = HADDR_UNDEF; /* Return value */ FUNC_ENTER_NOAPI(HADDR_UNDEF) - hlog_fast(h5mv, "%s: enter size %" PRIuHSIZE, __func__, size); /* check arguments */ HDassert(shared->vfd_swmr_md_fd >= 0); @@ -336,9 +332,6 @@ H5MV_alloc(H5F_t *f, hsize_t size) HDassert(H5F_addr_defined(ret_value)); done: - hlog_fast(h5mv, "%s: leave addr %" PRIuHADDR " size %" PRIuHSIZE, - __func__, ret_value, size); - FUNC_LEAVE_NOAPI(ret_value) } /* end H5MV_alloc() */ @@ -363,9 +356,6 @@ H5MV_free(H5F_t *f, haddr_t addr, hsize_t size) FUNC_ENTER_NOAPI(FAIL) - hlog_fast(h5mv, "%s: enter addr %" PRIuHADDR " size %" PRIuHSIZE, - __func__, addr, size); - /* check arguments */ HDassert(f); if(!H5F_addr_defined(addr) || 0 == size) @@ -381,9 +371,6 @@ H5MV_free(H5F_t *f, haddr_t addr, hsize_t size) */ htri_t status; /* "can absorb" status for section into */ - hlog_fast(h5mv, "%s: trying to avoid starting up free space manager", - __func__); - /* Try to shrink the file */ if((status = H5MV_try_shrink(f, addr, size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't check for absorbing block") @@ -393,11 +380,8 @@ H5MV_free(H5F_t *f, haddr_t addr, hsize_t size) /* If we are deleting the free space manager, leave now, to avoid * [re-]starting it: dropping free space section on the floor. */ - if(shared->fs_state_md == H5F_FS_STATE_DELETING) { - hlog_fast(h5mv, "%s: dropping addr %" PRIuHADDR - " size %" PRIuHSIZE " on the floor!", __func__, addr, size); + if(shared->fs_state_md == H5F_FS_STATE_DELETING) HGOTO_DONE(SUCCEED) - } /* There's either already a free space manager, or the freed * space isn't at the end of the file, so start up (or create) @@ -413,25 +397,18 @@ H5MV_free(H5F_t *f, haddr_t addr, hsize_t size) HDassert(shared->fs_man_md); - hlog_fast(h5mv, "%s: before H5FS_sect_add, addr %" PRIuHADDR - " size %" PRIuHSIZE, __func__, addr, size); - /* Add the section */ if(H5FS_sect_add(f, shared->fs_man_md, &node->sect_info, H5FS_ADD_RETURNED_SPACE, f) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space") node = NULL; - hlog_fast(h5mv, "%s: after H5FS_sect_add", __func__); - done: /* Release section node, if allocated and not added to section list or merged */ if(node) if(H5MV__sect_free(&node->sect_info) < 0) HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node") - hlog_fast(h5mv, "%s: leave %d", __func__, ret_value); - FUNC_LEAVE_NOAPI(ret_value) } /* end H5MV_free() */ -- cgit v0.12 From 7d53a8b8375ed235f2387cecce1016c914971006 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 04:34:09 -0800 Subject: Removed the rest of the hlog code --- MANIFEST | 3 - doc/Diagnostic-Logging.md | 88 ----------- src/CMakeLists.txt | 2 - src/H5C.c | 6 - src/H5FDvfd_swmr.c | 43 +----- src/H5FDvfd_swmr_private.h | 6 - src/H5Fvfd_swmr.c | 117 --------------- src/H5PB.c | 52 +------ src/Makefile.am | 3 +- src/hlog.c | 366 --------------------------------------------- src/hlog.h | 138 ----------------- 11 files changed, 5 insertions(+), 819 deletions(-) delete mode 100644 doc/Diagnostic-Logging.md delete mode 100644 src/hlog.c delete mode 100644 src/hlog.h diff --git a/MANIFEST b/MANIFEST index 66de8f2..0ee904a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -185,7 +185,6 @@ ./config/site-specific/BlankForm -./doc/Diagnostic-Logging.md ./doc/SWMR_Example.png ./doc/SWMRdataflow.png ./doc/VFD_SWMR_Punch_List.md @@ -529,8 +528,6 @@ ./src/hdf5.lnt _DO_NOT_DISTRIBUTE_ ./src/hdf5-win.lnt _DO_NOT_DISTRIBUTE_ ./src/hdf5-lin.lnt _DO_NOT_DISTRIBUTE_ -./src/hlog.c -./src/hlog.h ./src/COPYING ./src/H5.c ./src/H5checksum.c diff --git a/doc/Diagnostic-Logging.md b/doc/Diagnostic-Logging.md deleted file mode 100644 index e71e737..0000000 --- a/doc/Diagnostic-Logging.md +++ /dev/null @@ -1,88 +0,0 @@ -# The Hierarchical Log Library (`hlog`) - -A program uses the hierarchical log library, `hlog`, to organize -its diagnostic messages into categories and subcategories and to -turn on and off message categories to produce the most useful -diagnostic trace. - -A typical program will define one or more log *outlets*. An outlet -is a named target for diagnostic messages. Each outlet has a *state* -(*on*, *off*, or *pass*) and at most one *parent outlet*. Usually, the -parent-child relationships between outlets form a tree rooted at the -outlet "all", which is supplied by the library. Outlets may form a -"forest" if a program supplies its own root outlets. - -A program sends messages to an outlet using `hlog` API calls. -Messages sent to an outlet that is *on* are copied to the error -stream. Messages sent to an outlet that is *off* are discarded. -When a message is sent to an outlet in *pass* state, the `hlog` -uses the outlet ancestors to decide what to do with the message. - -## Sending messages with `hlog_fast` - -A program calls `hlog_fast(outlet name, format string, ...)` to -write a formatted message to the named outlet. `hlog_fast` uses -the outlet state to do decide what to do with the message. If the -outlet is *on*, then the message is written to the standard error -stream. If the outlet is *off*, then the message is discarded. -If the outlet is in state *pass*, and the outlet has no parent, -then the message is discarded. If the outlet does have a parent, -then `hlog_fast` looks at the parent state and decides whether to -discard, write, or recurse. - -`hlog_fast` precedes each diagnostic message with a timestamp (decimal -seconds with 9 digits right of the decimal point), a colon, and a single -space. Each message is followed with a newline ("\n"). The effective -timestamp resolution may be much less than one nanosecond. Timestamps -increase monotonically. The timestamp origin is currently unspecified. - -## Defining log outlets - -`hlog` provides macros for declaring outlets, and for statically -configuring an outlet, its parent, and its initial state. - -Use `HLOG_OUTLET_DECL(name)` to declare shared outlets in header -files. `HLOG_OUTLET_DECL(name)` declares an `extern` symbol. -There must not be any quotation marks on *name*. - -Use `HLOG_OUTLET_SHORT_DEFN(name, parent)` to define an outlet with the -given name and parent in state *pass*. There must not be any quotation -marks on *name*. - -Use `HLOG_OUTLET_MEDIUM_DEFN(name, parent, state)` to define an outlet -with the given name, parent, and state. The state is given by an -`hlog_outlet_state_t`, one of `HLOG_OUTLET_S_ON`, `HLOG_OUTLET_S_OFF`, -or `HLOG_OUTLET_S_PASS`. There must not be any quotation marks on -*name*. - -## Enabling and disabling outlets with the environment - -An environment variable, `HLOG`, sets initial outlet states for a -program. If `HLOG` may be set to the empty string, in which case -outlet states stay at their program defaults. `HLOG` may also be -set to one or more *outlet name*=*state* pairs, separated by either -whitespace or commas. *state* is one of *pass*, *on*, or *off*, -and *outlet-name* is a string matching `[_a-zA-Z][_a-zA-Z0-9]*`. -For example, to enable the `tick` outlet and `pbrm` outlets while -the program `./vfd_swmr_zoo_writer` runs, you can use this command -in `csh` or Bourne shell: - -``` -env HLOG="tick=on pbrm=on" ./vfd_swmr_zoo_writer -``` - -# Implementation notes - -`hlog_fast(outlet name, format string, ...)` is implemented as a -macro that only evaluates its format string or other arguments if -it decides to write the message to `stderr`. `hlog_fast` avoids -repeatedly walking child-parent links by caching its decision to -write or discard in the named outlet. - -# Future improvements - -The timestamp origin is unspecified, now. For the user's convenience, -the timestamp probably should be measured from `hlog` library -initialization. Also, `hlog` should provide a routine for setting -the timestamp origin to the current time. - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index af4920b..038948c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,6 @@ set (H5_SOURCES ${HDF5_SRC_DIR}/H5system.c ${HDF5_SRC_DIR}/H5timer.c ${HDF5_SRC_DIR}/H5trace.c - ${HDF5_SRC_DIR}/hlog.c ) set (H5_HDRS @@ -816,7 +815,6 @@ set (H5_PUBLIC_HEADERS set (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5private.h - ${HDF5_SRC_DIR}/hlog.h ${HDF5_SRC_DIR}/H5Apkg.h ${HDF5_SRC_DIR}/H5Aprivate.h diff --git a/src/H5C.c b/src/H5C.c index 9ebf0c6..3b094da 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -1325,13 +1325,7 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, entry_ptr = entry_ptr->pi_next; } - if (!found) { - hlog_fast(mdc_invalidation, "no MDC match for page %" PRIu64 - " length %" PRIu32 " tick %" PRIu64, page, length, tick); - } - done: - FUNC_LEAVE_NOAPI(ret_value) } /* H5C_evict_or_refresh_all_entries_in_page() */ diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 6e29376..bc82be5 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -103,12 +103,6 @@ static htri_t H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, H5FD_vfd_swmr_md_index *md_index, const H5FD_vfd_swmr_md_header *md_header); static herr_t H5FD__vfd_swmr_load_hdr_and_idx(H5FD_vfd_swmr_t *, hbool_t); -HLOG_OUTLET_SHORT_DEFN(index_motion, swmr); -HLOG_OUTLET_SHORT_DEFN(swmr_stats, swmr); -HLOG_OUTLET_SHORT_DEFN(swmr_read, swmr); -HLOG_OUTLET_SHORT_DEFN(swmr_read_exception, swmr_read); -HLOG_OUTLET_MEDIUM_DEFN(swmr_read_err, swmr_read_exception, HLOG_OUTLET_S_ON); - static const H5FD_class_t H5FD_vfd_swmr_g = { "vfd_swmr", /* name */ MAXADDR, /* maxaddr */ @@ -430,15 +424,8 @@ swmr_reader_close(H5FD_vfd_swmr_t *file) { vfd_swmr_reader_did_increase_tick_to(0); - if (file->api_elapsed_ticks != NULL) { - uint32_t i; - for (i = 0; i < file->api_elapsed_nbuckets; i++) { - hlog_fast(swmr_stats, - "%s: %" PRIu32 " ticks elapsed in API %" PRIu64 " times", - __func__, i, file->api_elapsed_ticks[i]); - } + if (file->api_elapsed_ticks != NULL) H5MM_xfree(file->api_elapsed_ticks); - } /* Close the metadata file */ if(file->md_fd >= 0 && HDclose(file->md_fd) < 0) { @@ -858,10 +845,6 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, entry = vfd_swmr_pageno_to_mdf_idx_entry(index, num_entries, target_page, false); - hlog_fast(swmr_read, "%s: enter type %d addr %" PRIuHADDR " size %zu " - "file %s", __func__, type, addr, size, - (entry == NULL) ? "lower" : "shadow"); - if (entry == NULL) { /* Cannot find addr in index, read from the underlying hdf5 file */ if(H5FD_read(file->hdf5_file_lf, type, addr, size, buf) < 0) { @@ -926,31 +909,14 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, * is John's hack to allow the library to find the superblock * signature. */ - if (!file->pb_configured) { - hlog_fast(swmr_read_exception, - "%s: skipping checksum, page buffer not configured", __func__); - } else if (entry->length != init_size) { - hlog_fast(swmr_read_exception, - "%s: skipping checksum, buffer size != entry size", __func__); - } else if (H5_checksum_metadata(buf, entry->length, 0) != entry->chksum) { + if (H5_checksum_metadata(buf, entry->length, 0) != entry->chksum) { H5FD_vfd_swmr_md_header tmp_header; - hlog_fast(swmr_read_err, "%s: bad checksum", __func__); - hlog_fast(swmr_read_err, "addr %" PRIuHADDR " page %" PRIuHADDR - " len %zu type %d ...", addr, addr / fs_page_size, init_size, type); - hlog_fast(swmr_read_err, "... index[%" PRId64 "] lower pgno %" PRIu64 - " shadow pgno %" PRIu64 " len %" PRIu32 " sum %" PRIx32, - (int64_t)(entry - index), entry->hdf5_page_offset, - entry->md_file_page_offset, entry->length, entry->chksum); - if (H5FD__vfd_swmr_header_deserialize(file, &tmp_header) != TRUE) { HGOTO_ERROR(H5E_VFL, H5E_CANTLOAD, FAIL, "checksum error in shadow file entry; could not load header"); } - hlog_fast(swmr_read_err, "... header tick last read %" PRIu64 - " latest %" PRIu64, file->md_header.tick_num, tmp_header.tick_num); - HGOTO_ERROR(H5E_VFL, H5E_CANTLOAD, FAIL, "checksum error in shadow file entry"); } @@ -1145,11 +1111,8 @@ H5FD__vfd_swmr_load_hdr_and_idx(H5FD_vfd_swmr_t *file, hbool_t open) if (rc != TRUE) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "could not read header"); - if (md_header.index_offset != last_index_offset) { - hlog_fast(index_motion, "index offset changed %" PRIu64 "\n", - md_header.index_offset); + if (md_header.index_offset != last_index_offset) last_index_offset = md_header.index_offset; - } if (open) ; // ignore tick number on open diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 74a937f..feb75c9 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -13,7 +13,6 @@ #define _H5FDvfd_swmr_private_H #include "H5queue.h" /* for TAILQ_* */ -#include "hlog.h" /* for TAILQ_* */ /* Forward declaration */ struct H5F_t; @@ -64,11 +63,6 @@ typedef TAILQ_HEAD(eot_queue, eot_queue_entry) eot_queue_t; extern eot_queue_t eot_queue_g; -HLOG_OUTLET_DECL(swmr); -HLOG_OUTLET_DECL(pbwr); -HLOG_OUTLET_DECL(shadow_index_reclaim); -HLOG_OUTLET_DECL(mdc_invalidation); - /***************************************/ /* Library-private Function Prototypes */ /***************************************/ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index fafff01..b408e54 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -48,7 +48,6 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5SMprivate.h" /* Shared Object Header Messages */ #include "H5Tprivate.h" /* Datatypes */ -#include "hlog.h" /****************/ /* Local Macros */ @@ -85,18 +84,6 @@ unsigned int vfd_swmr_api_entries_g = 0;/* Times the library was entered * on the 0->1 and 1->0 * transitions. */ -HLOG_OUTLET_SHORT_DEFN(swmr, all); -HLOG_OUTLET_SHORT_DEFN(eot, swmr); -HLOG_OUTLET_SHORT_DEFN(eotq, eot); -HLOG_OUTLET_SHORT_DEFN(shadow_defrees, swmr); -HLOG_OUTLET_MEDIUM_DEFN(noisy_shadow_defrees, shadow_defrees, - HLOG_OUTLET_S_OFF); -HLOG_OUTLET_SHORT_DEFN(shadow_index_enlarge, swmr); -HLOG_OUTLET_SHORT_DEFN(shadow_index_reclaim, swmr); -HLOG_OUTLET_SHORT_DEFN(shadow_index_update, swmr); -HLOG_OUTLET_SHORT_DEFN(tick, swmr); -HLOG_OUTLET_SHORT_DEFN(mdc_invalidation, swmr); - /* * The head of the end of tick queue (EOT queue) for files opened in either * VFD SWMR write or VFD SWMR read mode @@ -249,9 +236,6 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) HDassert(shared->tick_num != 0); vfd_swmr_reader_did_increase_tick_to(shared->tick_num); - hlog_fast(tick, "%s first tick %" PRIu64, - __func__, shared->tick_num); - #if 0 /* JRM */ HDfprintf(stderr, "##### initialized index: tick/used/len = %lld/%d/%d #####\n", @@ -347,7 +331,6 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) TAILQ_REMOVE(&shared->shadow_defrees, curr, link); H5FL_FREE(shadow_defree_t, curr); } - hlog_fast(shadow_defrees, "Emptied deferred shadow frees."); HDassert(TAILQ_EMPTY(&shared->shadow_defrees)); } else { /* For file flush */ @@ -372,9 +355,6 @@ shadow_range_defer_free(H5F_shared_t *shared, uint64_t offset, uint32_t length) shadow_defree->length = length; shadow_defree->tick_num = shared->tick_num; - if (TAILQ_EMPTY(&shared->shadow_defrees)) - hlog_fast(shadow_defrees, "Adding first deferred shadow free."); - TAILQ_INSERT_HEAD(&shared->shadow_defrees, shadow_defree, link); return 0; } @@ -474,10 +454,6 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, \ "error in allocating space from the metadata file") - hlog_fast(noisy_shadow_defrees, - "shadow index %" PRIu32 " page offset %" PRIu64 " -> %" PRIuHADDR, - i, index[i].md_file_page_offset * shared->fs_page_size, md_addr); - HDassert(md_addr % shared->fs_page_size == 0); /* Compute checksum and update the index entry */ @@ -558,20 +534,12 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, "unable to flush clean entry"); } - hlog_fast(noisy_shadow_defrees, - "released %" PRIu32 " bytes at %" PRIu64, - shadow_defree->length, shadow_defree->offset); - TAILQ_REMOVE(&shared->shadow_defrees, shadow_defree, link); H5FL_FREE(shadow_defree_t, shadow_defree); } - if (queue_was_nonempty && TAILQ_EMPTY(&shared->shadow_defrees)) - hlog_fast(shadow_defrees, "Removed last deferred shadow free."); - done: - FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_update_vfd_swmr_metadata_file() */ @@ -740,22 +708,11 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, for (i = j = ndeleted = 0; i < nentries; i++) { ie = &idx[i]; - if (ie->clean) { - hlog_fast(shadow_index_reclaim, - "Visiting clean shadow index slot %" PRIu32 - " lower page %" PRIu64 " last flush %" PRIu64 " ticks ago", - i, ie->hdf5_page_offset, tick_num - ie->tick_of_last_flush); - } - if (ie->clean && ie->tick_of_last_flush + max_lag < tick_num) { HDassert(!ie->garbage); HDassert(ie->entry_ptr == NULL); - hlog_fast(shadow_index_reclaim, - "Reclaiming shadow index slot %" PRIu32 - " lower page %" PRIu64, i, ie->hdf5_page_offset); - if (ie->md_file_page_offset != 0) { if (shadow_image_defer_free(shared, ie) == -1) return -1; @@ -992,9 +949,6 @@ update_eot: if(H5F_vfd_swmr_insert_entry_eot(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue") - hlog_fast(eot, "%s leave tick %" PRIu64 " idx len %" PRIu32, - __func__, shared->tick_num, shared->mdf_idx_entries_used); - done: FUNC_LEAVE_NOAPI(ret_value) } @@ -1119,10 +1073,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) HDassert(!shared->vfd_swmr_writer); HDassert(file); - hlog_fast(eot, "%s enter file %p index len %" PRIu32 " used %" PRIu32, - __func__, (void *)file, - shared->mdf_idx_len, shared->mdf_idx_entries_used); - /* 1) Direct the VFD SWMR reader VFD to load the current header * from the metadata file, and report the current tick. * @@ -1135,10 +1085,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, \ "error in retrieving tick_num from driver") - hlog_fast(tick, - "%s last tick %" PRIu64 " new tick %" PRIu64, - __func__, shared->tick_num, tmp_tick_num); - /* This is ok if we're entering the API, but it should * not happen if we're exiting the API. */ @@ -1246,13 +1192,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) */ HDassert(oent->length == nent->length); - hlog_fast(shadow_index_update, - "shadow page for slot %" PRIu32 " lower page %" PRIu64 - " moved, %" PRIu64 " -> %" PRIu64, i, - oent->hdf5_page_offset, - oent->md_file_page_offset, - nent->md_file_page_offset); - /* the page has been altered -- evict it and * any contained metadata cache entries. */ @@ -1274,10 +1213,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) * for several ticks, we can probably omit this. However, * lets not worry about this for the first cut. */ - hlog_fast(shadow_index_update, - "writer removed shadow index slot %" PRIu32 - " for page %" PRIu64, i, oent->hdf5_page_offset); - change[nchanges].pgno = oent->hdf5_page_offset; change[nchanges].length = oent->length; nchanges++; @@ -1288,10 +1223,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) * nent->hdf5_page_offset */ - hlog_fast(shadow_index_update, - "writer added shadow index slot %" PRIu32 - " for page %" PRIu64, j, nent->hdf5_page_offset); - /* The page has been added to the index. */ change[nchanges].pgno = nent->hdf5_page_offset; change[nchanges].length = nent->length; @@ -1303,9 +1234,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) for (; j < new_mdf_idx_entries_used; j++) { const H5FD_vfd_swmr_idx_entry_t *nent = &new_mdf_idx[j]; - hlog_fast(shadow_index_update, - "writer added shadow index slot %" PRIu32 - " for page %" PRIu64, j, nent->hdf5_page_offset); change[nchanges].pgno = nent->hdf5_page_offset; change[nchanges].length = nent->length; nchanges++; @@ -1320,11 +1248,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) * index. Evict it from the page buffer and also evict any * contained metadata cache entries */ - - hlog_fast(shadow_index_update, - "writer removed shadow index slot %" PRIu32 - " for page %" PRIu64, i, oent->hdf5_page_offset); - change[nchanges].pgno = oent->hdf5_page_offset; change[nchanges].length = oent->length; nchanges++; @@ -1339,10 +1262,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) } } for (i = 0; i < nchanges; i++) { - hlog_fast(mdc_invalidation, - "invalidating MDC entries at page %" PRIu64 - " length %" PRIu32 " tick %" PRIu64, - change[i].pgno, change[i].length, tmp_tick_num); if (H5C_evict_or_refresh_all_entries_in_page(f, change[i].pgno, change[i].length, tmp_tick_num) < 0) { @@ -1387,16 +1306,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) done: - hlog_fast(eot, "%s exit tick %" PRIu64 - " len %" PRIu32 " -> %" PRIu32 - " used %" PRIu32 " -> %" PRIu32 - " added %" PRIu32 " removed %" PRIu32 " moved %" PRIu32 " %s", - __func__, shared->tick_num, - shared->old_mdf_idx_len, shared->mdf_idx_len, - shared->old_mdf_idx_entries_used, shared->mdf_idx_entries_used, - entries_added, entries_removed, entries_moved, - (ret_value == SUCCEED) ? "success" : "failure"); - if (change != NULL) free(change); @@ -1415,12 +1324,6 @@ insert_eot_entry(eot_queue_entry_t *entry_ptr) break; } - hlog_fast(eotq, "%s: entry %p after %p file %p " - "tick %" PRIu64 " ending %jd.%09ld", __func__, - (void *)entry_ptr, (void *)prec_ptr, (void *)entry_ptr->vfd_swmr_file, - entry_ptr->tick_num, (intmax_t)entry_ptr->end_of_tick.tv_sec, - entry_ptr->end_of_tick.tv_nsec); - /* Insert the entry onto the EOT queue */ if (prec_ptr != NULL) TAILQ_INSERT_AFTER(&eot_queue_g, prec_ptr, entry_ptr, link); @@ -1441,20 +1344,10 @@ H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *entry) TAILQ_REMOVE(&eot_queue_g, entry, link); - hlog_fast(eotq, "%s: updating entry %p file %p " - "tick %" PRIu64 " ending %jd.%09ld", __func__, - (void *)entry, (void *)entry->vfd_swmr_file, - entry->tick_num, (intmax_t)entry->end_of_tick.tv_sec, - entry->end_of_tick.tv_nsec); - HDassert(entry->vfd_swmr_writer == shared->vfd_swmr_writer); entry->tick_num = shared->tick_num; entry->end_of_tick = shared->end_of_tick; - hlog_fast(eotq, "%s: ... to tick %" PRIu64 " ending %jd.%09ld", __func__, - entry->tick_num, (intmax_t)entry->end_of_tick.tv_sec, - entry->end_of_tick.tv_nsec); - insert_eot_entry(entry); } @@ -1487,11 +1380,6 @@ H5F_vfd_swmr_remove_entry_eot(H5F_t *f) } if (curr != NULL) { - hlog_fast(eotq, "%s: entry %p file %p " - "tick %" PRIu64 " ending %jd.%09ld", __func__, - (void *)curr, (void *)curr->vfd_swmr_file, curr->tick_num, - (intmax_t)curr->end_of_tick.tv_sec, - curr->end_of_tick.tv_nsec); TAILQ_REMOVE(&eot_queue_g, curr, link); curr = H5FL_FREE(eot_queue_entry_t, curr); } @@ -1632,9 +1520,6 @@ H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_shared_t *shared, shared->tick_num++; - hlog_fast(tick, "%s tick %" PRIu64 " -> %" PRIu64, - __func__, shared->tick_num - 1, shared->tick_num); - if ( H5PB_vfd_swmr__set_tick(shared) < 0 ) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, \ @@ -1951,8 +1836,6 @@ vfd_swmr_enlarge_shadow_index(H5F_t *f) FUNC_ENTER_NOAPI(NULL) - hlog_fast(shadow_index_enlarge, "Enlarging shadow index."); - old_mdf_idx = shared->mdf_idx; old_mdf_idx_len = shared->mdf_idx_len; diff --git a/src/H5PB.c b/src/H5PB.c index c98b094..12de5b4 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -45,8 +45,6 @@ #include "H5PBpkg.h" /* File access */ -#include "hlog.h" - /****************/ /* Local Macros */ /****************/ @@ -143,17 +141,6 @@ H5FL_DEFINE_STATIC(H5PB_t); /* Declare a free list to manage the H5PB_entry_t struct */ H5FL_DEFINE_STATIC(H5PB_entry_t); -HLOG_OUTLET_DECL(pagebuffer); -HLOG_OUTLET_SHORT_DEFN(pagebuffer, all); -HLOG_OUTLET_SHORT_DEFN(pb_access_sizes, pagebuffer); -HLOG_OUTLET_SHORT_DEFN(pbflush, pagebuffer); -HLOG_OUTLET_SHORT_DEFN(pbflush_entry, pbflush); -HLOG_OUTLET_SHORT_DEFN(pbio, pagebuffer); -HLOG_OUTLET_SHORT_DEFN(pbrd, pbio); -HLOG_OUTLET_SHORT_DEFN(pbwr, pbio); -HLOG_OUTLET_SHORT_DEFN(lengthen_pbentry, pagebuffer); -HLOG_OUTLET_SHORT_DEFN(pbrm, pagebuffer); - /*------------------------------------------------------------------------- * @@ -862,19 +849,11 @@ H5PB_flush(H5F_shared_t *shared) flush_ptr = entry_ptr; entry_ptr = entry_ptr->ht_next; - hlog_fast(pbflush, "%s: visiting %zu-byte page %" PRIu64, - __func__, flush_ptr->size, flush_ptr->page); if ( flush_ptr->is_dirty ) { - if (flush_ptr->delay_write_until != 0) { - hlog_fast(pbflush, "%s: delaying %zu-byte page %" PRIu64 - " until %" PRIu64 " (now %" PRIu64 ")", - __func__, flush_ptr->size, flush_ptr->page, - flush_ptr->delay_write_until, - shared->tick_num); + if (flush_ptr->delay_write_until != 0) continue; - } if ( H5PB__flush_entry(shared, pb_ptr, flush_ptr) < 0 ) @@ -967,20 +946,10 @@ H5PB_log_access_by_size_counts(const H5PB_t *pb) const size_t nslots = NELMTS(pb->access_size_count); size_t i, lo, hi; - hlog_fast(pb_access_sizes, "page buffer %p metadata accesses by size:", - (const void *)pb); - for (lo = 0, hi = pb->page_size, i = 0; i < nslots - 1; i++, lo = hi + 1, hi *= 2) { - hlog_fast(pb_access_sizes, - "%16" PRIu64 " accesses %8zu - %8zu bytes long", - pb->access_size_count[i], lo, hi); } - - hlog_fast(pb_access_sizes, - "%16" PRIu64 " accesses %8zu - greater bytes long", - pb->access_size_count[i], lo); } @@ -1179,10 +1148,6 @@ H5PB_read(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size, /* Sanity checks */ HDassert(shared); - hlog_fast(pbrd, "%s %p type %d %" PRIuHADDR " size %zu", - __func__, (void *)shared, type, addr, size); - - pb_ptr = shared->pb_ptr; if (pb_ptr != NULL && type != H5FD_MEM_DRAW) @@ -2333,9 +2298,6 @@ H5PB_vfd_swmr__update_index(H5F_t *f, H5PB__SEARCH_INDEX(pb_ptr, ie_ptr->hdf5_page_offset, entry, FAIL); if (entry == NULL || !entry->is_dirty) { - hlog_fast(shadow_index_reclaim, - "Marking shadow index slot %" PRIu32 " clean at tick %" PRIu64, - i, tick_num); idx_ent_not_in_tl_flushed++; ie_ptr->clean = TRUE; ie_ptr->tick_of_last_flush = tick_num; @@ -2522,9 +2484,6 @@ H5PB_write(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, size_t size, FUNC_ENTER_NOAPI(FAIL) - hlog_fast(pbwr, "%s %p type %d addr %" PRIuHADDR " size %zu", - __func__, (void *)shared, type, addr, size); - pb_ptr = shared->pb_ptr; if (pb_ptr != NULL && type != H5FD_MEM_DRAW) @@ -3338,10 +3297,6 @@ H5PB__flush_entry(H5F_shared_t *shared, H5PB_t *pb_ptr, H5PB_entry_t *const entr HDassert((pb_ptr->vfd_swmr_writer) || (!(entry_ptr->is_mpmde))); HDassert(0 == entry_ptr->delay_write_until); - hlog_fast(pbflush_entry, - "%s: flushing %zu-byte page %" PRIu64 " @ %" PRIuHADDR, - __func__, entry_ptr->size, entry_ptr->page, entry_ptr->addr); - /* Retrieve the 'eoa' for the file */ if ( HADDR_UNDEF == (eoa = H5FD_get_eoa(shared->lf, entry_ptr->mem_type)) ) @@ -4718,11 +4673,6 @@ H5PB__write_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, uint64_t last_page = page + roundup(size, pb_ptr->page_size) / pb_ptr->page_size; - hlog_fast(lengthen_pbentry, - "lengthening page %" PRIu64 " from %zu bytes to %zu, " - "last page %" PRIu64 "\n", page, entry_ptr->size, size, - last_page); - for (iter_page = page + 1; iter_page < last_page; iter_page++) { H5PB__SEARCH_INDEX(pb_ptr, iter_page, overlap, FAIL) HDassert(overlap == NULL); diff --git a/src/Makefile.am b/src/Makefile.am index cb3fa3c..bf565d8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -115,8 +115,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \ H5VLpassthru.c \ H5VM.c H5WB.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c \ - H5Zscaleoffset.c H5Zszip.c H5Ztrans.c \ - hlog.c + H5Zscaleoffset.c H5Zszip.c H5Ztrans.c # Only compile parallel sources if necessary if BUILD_PARALLEL_CONDITIONAL diff --git a/src/hlog.c b/src/hlog.c deleted file mode 100644 index d2d0e51..0000000 --- a/src/hlog.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2004, 2005, 2006, 2007 David Young. All rights reserved. - * - * See COPYING at the top of the HDF5 distribution for license terms. - */ -/* - * Copyright (c) 2004 Urbana-Champaign Independent Media Center. - * All rights reserved. - * - * See COPYING at the top of the HDF5 distribution for license terms. - */ -#include -#include -#include -#include -#include /* for uintmax_t */ -#include -#include -#include -#include - -#include -#include - -#include "hlog.h" -#include "H5time_private.h" - -TAILQ_HEAD(, hlog_outlet) hlog_outlets = TAILQ_HEAD_INITIALIZER(hlog_outlets); - -HLOG_OUTLET_TOP_DEFN(all); - -static struct timespec timestamp_zero; - -void hlog_init(void) _constructor; -static void hlog_init_timestamps(void); - -void -hlog_init(void) -{ - const char *settings0; - char *item, *settings; - - if ((settings0 = getenv("HLOG")) == NULL) - return; - - if ((settings = strdup(settings0)) == NULL) { - warn("%s: cannot duplicate settings string", __func__); - return; - } - - while ((item = strsep(&settings, " ,")) != NULL) { - hlog_outlet_state_t state; - char key[64 + 1], val[4 + 1]; // + 1 for the terminating NUL - int nconverted; - - nconverted = sscanf(item, " %64[0-9a-z_] = %4s ", key, val); - if (nconverted != 2) { - warnx("%s: malformed HLOG item \"%s\"", __func__, item); - continue; - } - - if (strcmp(val, "on") == 0 || strcmp(val, "yes") == 0) - state = HLOG_OUTLET_S_ON; - else if (strcmp(val, "off") == 0 || strcmp(val, "no") == 0) - state = HLOG_OUTLET_S_OFF; - else if (strcmp(val, "pass") == 0) - state = HLOG_OUTLET_S_PASS; - else { - warnx("%s: bad HLOG value \"%s\" in item \"%s\"", __func__, - val, item); - continue; - } - - if (hlog_set_state(key, state, true) == -1) { - warn("%s: could not set state for HLOG item \"%s\"", __func__, - item); - } - } - - free(settings); -} - - -static void -hlog_init_timestamps(void) -{ - static bool initialized = false; - - if (initialized) - return; - - if (clock_gettime(CLOCK_MONOTONIC, ×tamp_zero) == -1) - err(EXIT_FAILURE, "%s: clock_gettime", __func__); - - initialized = true; -} - -static void -hlog_print_time(void) -{ - struct timespec elapsed, now; - - hlog_init_timestamps(); - - if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) - err(EXIT_FAILURE, "%s: clock_gettime", __func__); - - timespecsub(&now, ×tamp_zero, &elapsed); - - fprintf(stderr, "%ju.%.9ld ", (uintmax_t)elapsed.tv_sec, elapsed.tv_nsec); -} - -void -vhlog(const char *fmt, va_list ap) -{ - hlog_print_time(); - (void)vfprintf(stderr, fmt, ap); - (void)fputc('\n', stderr); -} - -static char * -message_extend_stderr(const char *fmt0) -{ - static const char sep[] = ": "; - const char *m; - char *fmt; - size_t fmtlen; - - m = strerror(errno); - - fmtlen = strlen(fmt0) + strlen(m) + sizeof(sep); - - if ((fmt = malloc(fmtlen)) == NULL) { - err(EXIT_FAILURE, "%s: malloc failed", __func__); - return NULL; - } - - /* Note well the safe strcpy, strcat usage. Thank you. */ - strcpy(fmt, fmt0); - strcat(fmt, sep); - strcat(fmt, m); - - return fmt; -} - -static char * -message_extend(const char *fmt0) -{ - return message_extend_stderr(fmt0); -} - -void -vhlog_err(int status, const char *fmt0, va_list ap) -{ - char *fmt; - - if ((fmt = message_extend(fmt0)) == NULL) - exit(status); - vhlog(fmt, ap); - free(fmt); - - exit(status); -} - -void -vhlog_errx(int status, const char *fmt, va_list ap) -{ - vhlog(fmt, ap); - exit(status); -} - -void -vhlog_warn(const char *fmt0, va_list ap) -{ - char *fmt; - - if ((fmt = message_extend(fmt0)) == NULL) - return; - vhlog(fmt, ap); - free(fmt); -} - -void -vhlog_warnx(const char *fmt, va_list ap) -{ - vhlog(fmt, ap); -} - -void -hlog_err(int status, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vhlog_err(status, fmt, ap); - va_end(ap); -} - -void -hlog_errx(int status, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vhlog_errx(status, fmt, ap); - va_end(ap); -} - -void -hlog_warn(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vhlog_warn(fmt, ap); - va_end(ap); -} - -void -hlog_warnx(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vhlog_warnx(fmt, ap); - va_end(ap); -} - -struct hlog_outlet * -hlog_outlet_find_active(struct hlog_outlet *ls0) -{ - struct hlog_outlet *ls; - - HLOG_OUTLET_FOREACH(ls, ls0) { - switch (ls->ls_state) { - case HLOG_OUTLET_S_PASS: - continue; - case HLOG_OUTLET_S_OFF: - return NULL; - case HLOG_OUTLET_S_ON: - default: - return ls; - } - } - return NULL; -} - -void -hlog_always(struct hlog_outlet *ls _unused, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vhlog(fmt, ap); - va_end(ap); -} - -void -hlog_impl(struct hlog_outlet *ls0, const char *fmt, ...) -{ - struct hlog_outlet *ls; - va_list ap; - - if ((ls = hlog_outlet_find_active(ls0)) == NULL) { - ls0->ls_resolved = HLOG_OUTLET_S_OFF; - return; - } - - ls0->ls_resolved = HLOG_OUTLET_S_ON; - - va_start(ap, fmt); - vhlog(fmt, ap); - va_end(ap); -} - -static void -hlog_outlet_reset_all(void) -{ - struct hlog_outlet *ls; - - TAILQ_FOREACH(ls, &hlog_outlets, ls_next) - ls->ls_resolved = HLOG_OUTLET_S_PASS; -} - -struct hlog_outlet * -hlog_outlet_lookup(const char *name) -{ - struct hlog_outlet *ls; - - TAILQ_FOREACH(ls, &hlog_outlets, ls_next) { - if (strcmp(ls->ls_name, name) == 0) - return ls; - } - return NULL; -} - -static struct hlog_outlet * -hlog_outlet_create(const char *name) -{ - struct hlog_outlet *ls; - - if ((ls = calloc(1, sizeof(*ls))) == NULL) - return NULL; - else if ((ls->ls_name0 = strdup(name)) == NULL) { - free(ls); - return NULL; - } - ls->ls_name = ls->ls_name0; - ls->ls_rendezvous = true; - return ls; -} - -static void -hlog_outlet_destroy(struct hlog_outlet *ls) -{ - /*LINTED*/ - if (ls->ls_name0 != NULL) - free(ls->ls_name0); - free(ls); -} - -int -hlog_set_state(const char *name, hlog_outlet_state_t state, bool rendezvous) -{ - struct hlog_outlet *ls; - errno = 0; - - switch (state) { - case HLOG_OUTLET_S_PASS: - case HLOG_OUTLET_S_OFF: - case HLOG_OUTLET_S_ON: - break; - default: - errno = EINVAL; - return -1; - } - if ((ls = hlog_outlet_lookup(name)) == NULL && !rendezvous) { - errno = ESRCH; - return -1; - } else if (ls == NULL) { - if ((ls = hlog_outlet_create(name)) == NULL) - return -1; - TAILQ_INSERT_TAIL(&hlog_outlets, ls, ls_next); - } - ls->ls_state = state; - hlog_outlet_reset_all(); - return 0; -} - -void -hlog_outlet_register(struct hlog_outlet *ls_arg) -{ - struct hlog_outlet *ls; - if ((ls = hlog_outlet_lookup(ls_arg->ls_name)) == NULL || - ls->ls_rendezvous) { - TAILQ_INSERT_TAIL(&hlog_outlets, ls_arg, ls_next); - if (ls == NULL) - return; - warnx("%s: rendezvous with log-outlet '%s'", __func__, - ls->ls_name); - ls_arg->ls_state = ls->ls_state; - TAILQ_REMOVE(&hlog_outlets, ls, ls_next); - hlog_outlet_destroy(ls); - } else - warnx("%s: duplicate log-outlet, '%s'", __func__, ls->ls_name); -} diff --git a/src/hlog.h b/src/hlog.h deleted file mode 100644 index 2489a47..0000000 --- a/src/hlog.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2004, 2005, 2006, 2007 David Young. All rights reserved. - * - * See COPYING at the top of the HDF5 distribution for license terms. - */ -/* - * Copyright (c) 2004 Urbana-Champaign Independent Media Center. - * All rights reserved. - * - * See COPYING at the top of the HDF5 distribution for license terms. - */ -#ifndef _HLOG_H -#define _HLOG_H - -#include -#include -#include -#include - -#include "H5queue.h" - -#ifndef _unused -#define _unused __attribute__((unused)) -#endif - -#ifndef _constructor -#define _constructor __attribute__((constructor)) -#endif - -#ifndef _noreturn -#define _noreturn __attribute__((__noreturn__)) -#endif - -#ifndef _printflike -#define _printflike(_fmt, _args) \ - __attribute__((__format__(__printf__,_fmt,_args))) -#endif - -enum hlog_outlet_state { - HLOG_OUTLET_S_PASS = 0 - , HLOG_OUTLET_S_OFF = 1 - , HLOG_OUTLET_S_ON = 2 -}; - -typedef enum hlog_outlet_state hlog_outlet_state_t; - -struct hlog_outlet { - hlog_outlet_state_t ls_resolved; - struct hlog_outlet *ls_parent; - hlog_outlet_state_t ls_state; - const char *ls_name; - char *ls_name0; - bool ls_rendezvous; - TAILQ_ENTRY(hlog_outlet) ls_next; -}; - -typedef struct hlog_outlet hlog_outlet_t; - -#define HLOG_CONSTRUCTOR(__sym) \ -void hlog_constructor_##__sym(void) _constructor; \ -void \ -hlog_constructor_##__sym(void) \ -{ \ - hlog_outlet_register(&__sym); \ -} \ -void hlog_undefined_##__sym(void) _constructor - -#define HLOG_OUTLET_FOREACH(__le, __le0) \ - for ((__le) = (__le0); (__le) != NULL; (__le) = (__le)->ls_parent) - -#define HLOG_OUTLET_DECL1(__sym) extern struct hlog_outlet __sym - -#define HLOG_JOIN_SYMS(x, y) x ## y - -#define HLOG_PREFIX(_sfx) HLOG_JOIN_SYMS(hlog_gbl_, _sfx) - -#define HLOG_OUTLET_DECL(__name) HLOG_OUTLET_DECL1(HLOG_PREFIX(__name)) - -#define HLOG_OUTLET_DEFN(__sym, __name, __parent, __state) \ - struct hlog_outlet __sym = { \ - .ls_name = __name \ - , .ls_parent = (__parent) \ - , .ls_state = (__state) \ - }; \ - HLOG_CONSTRUCTOR(__sym) - -#define HLOG_OUTLET_MEDIUM_DEFN(__name, __parent, __state) \ - HLOG_OUTLET_DEFN(HLOG_PREFIX(__name), #__name, &HLOG_PREFIX(__parent), \ - __state) - -#define HLOG_OUTLET_SHORT_DEFN(__name, __parent) \ - HLOG_OUTLET_MEDIUM_DEFN(__name, __parent, HLOG_OUTLET_S_PASS) - -#define HLOG_OUTLET_TOP_DEFN(__name) \ - HLOG_OUTLET_DEFN(HLOG_PREFIX(__name), #__name, NULL, HLOG_OUTLET_S_PASS) - -HLOG_OUTLET_DECL(all); - -#define hlog(_name, _fmt, ...) \ - hlog_impl(&HLOG_PREFIX(_name), _fmt, __VA_ARGS__) - -#define hlog_fast(_name, ...) \ - do { \ - hlog_outlet_t *_ls0 = &HLOG_PREFIX(_name); \ - \ - if (_ls0->ls_resolved == HLOG_OUTLET_S_OFF) \ - break; \ - else if (_ls0->ls_resolved == HLOG_OUTLET_S_ON) \ - hlog_always(_ls0, __VA_ARGS__); \ - else \ - hlog_impl(_ls0, __VA_ARGS__); \ - } while (/*CONSTCOND*/0) - -struct hlog_outlet *hlog_outlet_find_active(struct hlog_outlet *); -void hlog_outlet_register(struct hlog_outlet *); -struct hlog_outlet *hlog_outlet_lookup(const char *); -int hlog_set_state(const char *, hlog_outlet_state_t, bool); - -void vhlog(const char *, va_list) _printflike(1,0); - -void vhlog_warn(const char *, va_list) _printflike(1,0); -void vhlog_warnx(const char *, va_list) _printflike(1,0); -void vhlog_err(int, const char *, va_list) _printflike(2,0) _noreturn; -void vhlog_errx(int, const char *, va_list) _printflike(2,0) _noreturn; - -void hlog_warnx(const char *, ...) _printflike(1,2); -void hlog_warn(const char *, ...) _printflike(1,2); - -void hlog_err(int, const char *, ...) _printflike(2,3) _noreturn; -void hlog_errx(int, const char *, ...) _printflike(2,3) _noreturn; - -void hlog_always(struct hlog_outlet *, const char *, ...) - _printflike(2,3); - -void hlog_impl(struct hlog_outlet *, const char *, ...) - _printflike(2,3); - -#endif /* _HLOG_H */ -- cgit v0.12 From 0455457cc743f290cc748903306b3a9ec4beb4d8 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 05:20:03 -0800 Subject: Switch to hbool_t and TRUE/FALSE in library code --- src/H5FDvfd_swmr.c | 10 +++++----- src/H5FDvfd_swmr_private.h | 6 +++--- src/H5Fvfd_swmr.c | 20 ++++++++++---------- src/H5PB.c | 40 ++++++++++++++++++++-------------------- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index bc82be5..3a7a5c5 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -64,7 +64,7 @@ typedef struct H5FD_vfd_swmr_t { /* and to FALSE otherwise. */ /* Used for sanity checking. */ H5F_vfd_swmr_config_t config; - bool writer; /* True iff configured to write. + hbool_t writer; /* True iff configured to write. * All methods on a write-mode * SWMR VFD instance are passed * to the lower VFD instance. @@ -263,7 +263,7 @@ static herr_t H5FD__swmr_reader_open(H5FD_vfd_swmr_t *file) { h5_retry_t retry; - bool do_try; /* more tries remain */ + hbool_t do_try; /* more tries remain */ herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC @@ -555,7 +555,7 @@ H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl) H5FD_vfd_swmr_t *other = (H5FD_vfd_swmr_t *)_other; H5P_genplist_t *plist; H5F_vfd_swmr_config_t *config; - bool equal_configs; + hbool_t equal_configs; if (H5FD_cmp(self->hdf5_file_lf, other->hdf5_file_lf) != 0) return _other; @@ -843,7 +843,7 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, target_page = addr / fs_page_size; entry = vfd_swmr_pageno_to_mdf_idx_entry(index, num_entries, target_page, - false); + FALSE); if (entry == NULL) { /* Cannot find addr in index, read from the underlying hdf5 file */ @@ -1083,7 +1083,7 @@ done: static herr_t H5FD__vfd_swmr_load_hdr_and_idx(H5FD_vfd_swmr_t *file, hbool_t open) { - bool do_try; + hbool_t do_try; h5_retry_t retry; H5FD_vfd_swmr_md_header md_header; /* Metadata file header, take 1 */ H5FD_vfd_swmr_md_header md_header_two; /* Metadata file header, take 2 */ diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index feb75c9..551adaa 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -74,10 +74,10 @@ H5_DLL herr_t H5F_update_vfd_swmr_metadata_file(struct H5F_t *f, H5_DLL herr_t H5F_vfd_swmr_writer__delay_write(struct H5F_shared_t *, uint64_t, uint64_t *); H5_DLL herr_t H5F_vfd_swmr_writer__prep_for_flush_or_close(struct H5F_t *f); -herr_t H5F_vfd_swmr_process_eot_queue(bool); -H5_DLL herr_t H5F_vfd_swmr_writer_end_of_tick(struct H5F_t *f, bool); +herr_t H5F_vfd_swmr_process_eot_queue(hbool_t); +H5_DLL herr_t H5F_vfd_swmr_writer_end_of_tick(struct H5F_t *f, hbool_t); H5_DLL herr_t H5F_vfd_swmr_writer__dump_index(struct H5F_shared_t *); -H5_DLL herr_t H5F_vfd_swmr_reader_end_of_tick(struct H5F_t *f, bool); +H5_DLL herr_t H5F_vfd_swmr_reader_end_of_tick(struct H5F_t *f, hbool_t); H5_DLL herr_t H5F_vfd_swmr_remove_entry_eot(struct H5F_t *f); H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f); diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index b408e54..1ff9ef7 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -412,7 +412,7 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, haddr_t md_addr; /* Address in the metadata file */ uint32_t i; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - bool queue_was_nonempty; + hbool_t queue_was_nonempty; FUNC_ENTER_NOAPI(FAIL) @@ -612,7 +612,7 @@ H5F_vfd_swmr_writer__delay_write(H5F_shared_t *shared, uint64_t page, ie_ptr = NULL; } else { ie_ptr = vfd_swmr_pageno_to_mdf_idx_entry(idx, - shared->mdf_idx_entries_used, page, false); + shared->mdf_idx_entries_used, page, FALSE); } if (ie_ptr == NULL) @@ -678,7 +678,7 @@ H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f) * tick so as to avoid attempts to flush entries on the page buffer * tick list that were modified during the current tick. */ - if ( H5F_vfd_swmr_writer_end_of_tick(f, true) < 0 ) + if ( H5F_vfd_swmr_writer_end_of_tick(f, TRUE) < 0 ) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, \ "H5F_vfd_swmr_writer_end_of_tick() failed.") @@ -789,7 +789,7 @@ clean_shadow_index(H5F_t *f, uint32_t nentries, *------------------------------------------------------------------------- */ herr_t -H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, bool wait_for_reader) +H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) { H5F_shared_t *shared = f->shared; uint32_t idx_entries_added = 0; @@ -798,7 +798,7 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, bool wait_for_reader) uint32_t idx_ent_not_in_tl = 0; uint32_t idx_ent_not_in_tl_flushed = 0; herr_t ret_value = SUCCEED; /* Return value */ - bool incr_tick = false; + hbool_t incr_tick = FALSE; FUNC_ENTER_NOAPI(FAIL) @@ -810,7 +810,7 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, bool wait_for_reader) wait_for_reader)) goto update_eot; - incr_tick = true; + incr_tick = TRUE; /* 1) If requested, flush all raw data to the HDF5 file. * @@ -1047,7 +1047,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, bool entering_api) +H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api) { uint64_t tmp_tick_num = 0; H5FD_vfd_swmr_idx_entry_t * tmp_mdf_idx; @@ -1940,7 +1940,7 @@ H5F__vfd_swmr_writer__wait_a_tick(H5F_t *f) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "HDnanosleep() failed.") - if ( H5F_vfd_swmr_writer_end_of_tick(f, false) < 0 ) + if ( H5F_vfd_swmr_writer_end_of_tick(f, FALSE) < 0 ) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, \ "H5F_vfd_swmr_writer_end_of_tick() failed.") @@ -1952,7 +1952,7 @@ done: } /* H5F__vfd_swmr_writer__wait_a_tick() */ herr_t -H5F_vfd_swmr_process_eot_queue(bool entering_api) +H5F_vfd_swmr_process_eot_queue(hbool_t entering_api) { struct timespec now; eot_queue_entry_t *first_head, *head; @@ -1981,7 +1981,7 @@ H5F_vfd_swmr_process_eot_queue(bool entering_api) if (timespeccmp(&head->end_of_tick, &shared->end_of_tick, <)) { H5F_vfd_swmr_update_entry_eot(head); } else if (shared->vfd_swmr_writer) { - if (H5F_vfd_swmr_writer_end_of_tick(f, false) < 0) + if (H5F_vfd_swmr_writer_end_of_tick(f, FALSE) < 0) HGOTO_ERROR(H5E_FUNC, H5E_CANTSET, FAIL, "end of tick error for VFD SWMR writer"); } else if (H5F_vfd_swmr_reader_end_of_tick(f, entering_api) < 0) { diff --git a/src/H5PB.c b/src/H5PB.c index 12de5b4..66e0687 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -89,7 +89,7 @@ static herr_t H5PB__create_new_page(H5PB_t *pb_ptr, haddr_t addr, size_t size, static void H5PB__deallocate_page(H5PB_entry_t *entry_ptr); -static herr_t H5PB__evict_entry(H5F_shared_t *, H5PB_entry_t *, bool, bool); +static herr_t H5PB__evict_entry(H5F_shared_t *, H5PB_entry_t *, hbool_t, hbool_t); static herr_t H5PB__flush_entry(H5F_shared_t *, H5PB_t *, H5PB_entry_t *); @@ -760,7 +760,7 @@ H5PB_dest(H5F_shared_t *shared) "Can't flush entry") } - if ( H5PB__evict_entry(shared, evict_ptr, TRUE, true) < 0 ) + if ( H5PB__evict_entry(shared, evict_ptr, TRUE, TRUE) < 0 ) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "forced eviction failed") @@ -1453,13 +1453,13 @@ done: * this routine performs an O(n) copy of index entries. */ static int -shadow_idx_entry_remove(H5F_shared_t *shared, uint64_t page, bool only_mark) +shadow_idx_entry_remove(H5F_shared_t *shared, uint64_t page, hbool_t only_mark) { ptrdiff_t i; H5FD_vfd_swmr_idx_entry_t *entry; entry = vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, - shared->mdf_idx_entries_used, page, false); + shared->mdf_idx_entries_used, page, FALSE); if (entry == NULL) return 0; @@ -1471,7 +1471,7 @@ shadow_idx_entry_remove(H5F_shared_t *shared, uint64_t page, bool only_mark) } if (only_mark) { - entry->garbage = true; + entry->garbage = TRUE; return 0; } @@ -1590,11 +1590,11 @@ H5PB_remove_entry(H5F_shared_t *shared, haddr_t addr) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "mark entry clean failed") - if ( H5PB__evict_entry(shared, entry_ptr, TRUE, false) < 0 ) + if ( H5PB__evict_entry(shared, entry_ptr, TRUE, FALSE) < 0 ) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, "forced eviction failed") - HDassert(!shared->vfd_swmr_writer || vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page, false) == NULL); + HDassert(!shared->vfd_swmr_writer || vfd_swmr_pageno_to_mdf_idx_entry(shared->mdf_idx, shared->mdf_idx_entries_used, page, FALSE) == NULL); } done: @@ -1924,7 +1924,7 @@ H5PB_vfd_swmr__release_delayed_writes(H5F_shared_t *shared) HGOTO_ERROR(H5E_PAGEBUF, H5E_WRITEERROR, FAIL, \ "flush of mpmde failed") - if ( H5PB__evict_entry(shared, entry_ptr, TRUE, false) < 0 ) + if ( H5PB__evict_entry(shared, entry_ptr, TRUE, FALSE) < 0 ) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "eviction of mpmde failed") @@ -2003,7 +2003,7 @@ H5PB_vfd_swmr__release_tick_list(H5F_shared_t *shared) HGOTO_ERROR(H5E_PAGEBUF, H5E_WRITEERROR, FAIL, \ "flush of mpmde failed") - if ( H5PB__evict_entry(shared, entry_ptr, TRUE, false) < 0 ) + if ( H5PB__evict_entry(shared, entry_ptr, TRUE, FALSE) < 0 ) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "eviction of mpmde failed") @@ -2217,7 +2217,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, /* see if the shadow index already contains an entry for *entry. */ ie_ptr = vfd_swmr_pageno_to_mdf_idx_entry(idx, - shared->mdf_idx_entries_used, target_page, false); + shared->mdf_idx_entries_used, target_page, FALSE); if ( ie_ptr == NULL ) { /* alloc new entry in the metadata file index*/ uint32_t new_index_entry_index; @@ -2245,8 +2245,8 @@ H5PB_vfd_swmr__update_index(H5F_t *f, /* ie_ptr->clean initialized below */ /* ie_ptr->tick_of_last_flush initialized below */ ie_ptr->delayed_flush = entry->delay_write_until; - ie_ptr->moved_to_lower_file = false; - ie_ptr->garbage = false; + ie_ptr->moved_to_lower_file = FALSE; + ie_ptr->garbage = FALSE; ie_ptr->length = (uint32_t)entry->size; } else { @@ -2271,7 +2271,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, ie_ptr->entry_ptr = entry->image_ptr; ie_ptr->tick_of_last_change = tick_num; HDassert(entry->is_dirty); - ie_ptr->clean = false; + ie_ptr->clean = FALSE; ie_ptr->tick_of_last_flush = 0; } @@ -3147,8 +3147,8 @@ H5PB__deallocate_page(H5PB_entry_t *entry_ptr) *------------------------------------------------------------------------- */ static herr_t -H5PB__evict_entry(H5F_shared_t *shared, H5PB_entry_t *entry_ptr, bool force, - bool only_mark) +H5PB__evict_entry(H5F_shared_t *shared, H5PB_entry_t *entry_ptr, hbool_t force, + hbool_t only_mark) { H5PB_t *pb_ptr = shared->pb_ptr; herr_t ret_value = SUCCEED; /* Return value */ @@ -3643,7 +3643,7 @@ H5PB__make_space(H5F_shared_t *shared, H5PB_t *pb_ptr, H5FD_mem_t inserted_type) evict_ptr = search_ptr; search_ptr = search_ptr->prev; - if ( H5PB__evict_entry(shared, evict_ptr, FALSE, false) < 0 ) + if ( H5PB__evict_entry(shared, evict_ptr, FALSE, FALSE) < 0 ) HGOTO_ERROR(H5E_PAGEBUF, H5E_WRITEERROR, FAIL, \ "Can't evict entry") @@ -4108,7 +4108,7 @@ H5PB__read_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, HDassert( ! ( entry_ptr->is_dirty ) ); if ( H5PB__evict_entry(shared, entry_ptr, - TRUE, false) < 0 ) + TRUE, FALSE) < 0 ) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "forced eviction failed (1)") @@ -4692,7 +4692,7 @@ H5PB__write_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, entry_ptr->image_ptr = H5MM_xfree(entry_ptr->image_ptr); entry_ptr->image_ptr = new_image; - entry_ptr->is_mpmde = true; + entry_ptr->is_mpmde = TRUE; entry_ptr->size = size; if (entry_ptr->modified_this_tick) @@ -4769,7 +4769,7 @@ H5PB__write_meta(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, * already present. */ if (pb_ptr->vfd_swmr_writer && !entry_ptr->modified_this_tick) { - entry_ptr->modified_this_tick = true; + entry_ptr->modified_this_tick = TRUE; H5PB__INSERT_IN_TL(pb_ptr, entry_ptr, FAIL) } @@ -4924,7 +4924,7 @@ H5PB__write_raw(H5F_shared_t *shared, H5FD_mem_t type, haddr_t addr, HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "mark entry clean failed") - if (H5PB__evict_entry(shared, entry_ptr, TRUE, false) < 0) + if (H5PB__evict_entry(shared, entry_ptr, TRUE, FALSE) < 0) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "forced eviction failed (1)") -- cgit v0.12 From 132dd66269db2b8e3e158fdbdc3bae80c989b993 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 05:42:17 -0800 Subject: Fixes a bug from when the hlog code was removed --- src/H5FDvfd_swmr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 3a7a5c5..405bcd7 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -909,7 +909,8 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, * is John's hack to allow the library to find the superblock * signature. */ - if (H5_checksum_metadata(buf, entry->length, 0) != entry->chksum) { + if (file->pb_configured && entry->length == init_size + && H5_checksum_metadata(buf, entry->length, 0) != entry->chksum) { H5FD_vfd_swmr_md_header tmp_header; if (H5FD__vfd_swmr_header_deserialize(file, &tmp_header) != TRUE) { -- cgit v0.12 From 69b2061d68aa85c8925c15a334fc5c3fb12e377f Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 06:42:50 -0800 Subject: HD prefix and hbool_t changes in test/vfd_swmr.c --- test/vfd_swmr.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index b140813..321f85f 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -835,7 +835,7 @@ decisleep(uint32_t tenths) struct timespec delay = {.tv_sec = tenths / 10, .tv_nsec = tenths * 100 * 1000 * 1000}; - while (nanosleep(&delay, &delay) == -1 && errno == EINTR) + while (HDnanosleep(&delay, &delay) == -1 && errno == EINTR) ; // do nothing } @@ -948,7 +948,7 @@ test_writer_md(void) decisleep(my_config->tick_len); /* Create a chunked dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dcreate2(fid, dname, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -981,7 +981,7 @@ test_writer_md(void) decisleep(my_config->tick_len); /* Open the dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1015,7 +1015,7 @@ test_writer_md(void) decisleep(my_config->tick_len); /* Open the dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1503,7 +1503,7 @@ test_reader_md_concur(void) decisleep(config_writer->tick_len); /* Create a chunked dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dcreate2(fid_writer, dname, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1581,7 +1581,7 @@ test_reader_md_concur(void) decisleep(config_writer->tick_len); /* Open the dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dopen2(fid_writer, dname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1636,7 +1636,7 @@ test_reader_md_concur(void) decisleep(config_writer->tick_len); /* Open the dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dopen2(fid_writer, dname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -1690,7 +1690,7 @@ test_reader_md_concur(void) decisleep(config_writer->tick_len); /* Open the dataset */ - sprintf(dname, "dset %d", i); + HDsprintf(dname, "dset %d", i); if((did = H5Dopen2(fid_writer, dname, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR @@ -3071,7 +3071,7 @@ test_shadow_index_lookup(void) char vector[8]; unsigned seed = 1; unsigned i, j, failj = UINT_MAX; - bool have_failj = false; + hbool_t have_failj = FALSE; unsigned long tmpl; char *ostate; const char *seedvar = "H5_SHADOW_INDEX_SEED"; @@ -3085,7 +3085,7 @@ test_shadow_index_lookup(void) nerrors = 1; goto out; case 0: - seed = (unsigned int)time(NULL); + seed = (unsigned int)HDtime(NULL); break; default: seed = (unsigned int)tmpl; @@ -3101,55 +3101,55 @@ test_shadow_index_lookup(void) break; default: failj = (unsigned int)tmpl; - have_failj = true; + have_failj = TRUE; break; } ostate = initstate(seed, vector, _arraycount(vector)); - size[5] = (uint32_t)(1024 + random() % (16 * 1024 * 1024 - 1024)); + size[5] = (uint32_t)(1024 + HDrandom() % (16 * 1024 * 1024 - 1024)); for (i = 0; i < _arraycount(size); i++) { uint32_t cursize = size[i]; const uint64_t modulus = UINT64_MAX / MAX(1, cursize); uint64_t pageno; - assert(modulus > 1); // so that modulus - 1 > 0, below + HDassert(modulus > 1); // so that modulus - 1 > 0, below - idx = (cursize == 0) ? NULL : calloc(cursize, sizeof(*idx)); + idx = (cursize == 0) ? NULL : HDcalloc(cursize, sizeof(*idx)); if (idx == NULL && cursize != 0) { - fprintf(stderr, "couldn't allocate %" PRIu32 " indices\n", + HDfprintf(stderr, "couldn't allocate %" PRIu32 " indices\n", cursize); - exit(EXIT_FAILURE); + HDexit(EXIT_FAILURE); } - for (pageno = (uint64_t)random() % modulus, j = 0; + for (pageno = (uint64_t)HDrandom() % modulus, j = 0; j < cursize; - j++, pageno += 1 + (uint64_t)random() % (modulus - 1)) { + j++, pageno += 1 + (uint64_t)HDrandom() % (modulus - 1)) { idx[j].hdf5_page_offset = pageno; } for (j = 0; j < cursize; j++) { H5FD_vfd_swmr_idx_entry_t *found; found = vfd_swmr_pageno_to_mdf_idx_entry(idx, cursize, - idx[j].hdf5_page_offset, false); + idx[j].hdf5_page_offset, FALSE); if ((have_failj && failj == j) || found != &idx[j]) break; } if (j < cursize) { - printf("\nshadow-index entry %d lookup, pageno %" PRIu64 + HDprintf("\nshadow-index entry %d lookup, pageno %" PRIu64 ", index size %" PRIu32 ", seed %u", j, idx[j].hdf5_page_offset, cursize, seed); nerrors++; } if (idx != NULL) - free(idx); + HDfree(idx); } (void)setstate(ostate); out: if (nerrors == 0) PASSED(); else - printf(" FAILED\n"); + HDprintf(" FAILED\n"); return nerrors; } -- cgit v0.12 From c18b6eaea86281a478c61af5a342e76d4b6fce34 Mon Sep 17 00:00:00 2001 From: vchoi Date: Tue, 2 Mar 2021 11:59:33 -0600 Subject: Add test settings for vfd_swmr_bigset_writer.c based on HDF5TestExpress: Default, Exhaustive, and quick runs. --- test/testvfdswmr.sh.in | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index a66ddf4..a2e47b1 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -40,6 +40,30 @@ nsofterrors=0 # soft errors are expected to occur some of the time # on a couple of nondeterministic tests. ############################################################################### +## test parameters for vfd_swmr_bigset_writer.c based on HDF5TestExpress: +## 0: Exhaustive run: Tests take a long time to run. +## 1: Default run. +## 2+: Quick run +############################################################################### +if [ -z $HDF5TestExpress ]; then # Set to default when not set + HDF5TestExpress=1 +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) +if [[ "$HDF5TestExpress" -eq 0 ]] ; then # Setting for exhaustive run + BIGSET_n=50 + BIGSET_few_s=40 + BIGSET_many_s=1000 +elif [[ "$HDF5TestExpress" -gt 1 ]]; then # Setting for quick run + BIGSET_n=10 + BIGSET_few_s=10 + BIGSET_many_s=100 +fi + +############################################################################### ## definitions for message file to coordinate test runs ############################################################################### WRITER_MESSAGE=VFD_SWMR_WRITER_MESSAGE # The message file created by writer that the open is complete @@ -641,11 +665,11 @@ 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 50 $options -s 1000 -r 16 -c 16 -q & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n 50 $options -s 1000 -r 16 -c 16 -q -W & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q -W & pid_reader=$! # Wait for the reader to finish before signalling the @@ -690,11 +714,11 @@ 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 50 $options -s 40 -r 256 -c 256 -q & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n 50 $options -s 40 -r 256 -c 256 -q -W & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q -W & pid_reader=$! # Wait for the reader to finish before signalling the -- cgit v0.12 From c7518ef2995ed060761c375223e797ea2f8c24bf Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 15:19:31 -0800 Subject: Fixes a missing declaration for H5_get_win32_times() --- src/H5win32defs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 71162eb..8a73182 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -174,6 +174,7 @@ extern "C" { H5_DLL const wchar_t *H5_get_utf16_str(const char *s); H5_DLL int Wopen_utf8(const char *path, int oflag, ...); H5_DLL int Wremove_utf8(const char *path); + H5_DLL int H5_get_win32_times(H5_timevals_t* tvs); /* Round functions only needed for VS2012 and earlier. * They are always built to ensure they don't go stale and -- cgit v0.12 From 99237a729181c4143c91cf333575f27befd9cff3 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 16:04:42 -0800 Subject: Switch to using H5_nanosleep() instead of HDnanosleep() * Just in the main library and test/vfd_swmr.c * VFD SWMR acceptance tests still use HDnanosleep() directly --- src/H5Fvfd_swmr.c | 26 ++++++-------------------- test/vfd_swmr.c | 12 +++--------- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 1ff9ef7..76748fe 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1916,39 +1916,25 @@ H5F__vfd_swmr_writer__wait_a_tick(H5F_t *f) struct timespec req; struct timespec rem; uint64_t tick_in_nsec; - H5F_shared_t *shared = f->shared; + H5F_shared_t *shared; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC + HDassert(f); + shared = f->shared; HDassert(shared->vfd_swmr); HDassert(shared->vfd_swmr_writer); tick_in_nsec = shared->vfd_swmr_config.tick_len * nanosecs_per_tenth_sec; - req.tv_nsec = (long)(tick_in_nsec % nanosecs_per_second); - req.tv_sec = (time_t)(tick_in_nsec / nanosecs_per_second); - - result = HDnanosleep(&req, &rem); - - while ( result == -1 ) { - - req = rem; - result = HDnanosleep(&req, &rem); - } - if ( result != 0 ) + H5_nanosleep(tick_in_nsec); - HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "HDnanosleep() failed.") - - if ( H5F_vfd_swmr_writer_end_of_tick(f, FALSE) < 0 ) - - HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, \ - "H5F_vfd_swmr_writer_end_of_tick() failed.") + if (H5F_vfd_swmr_writer_end_of_tick(f, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "H5F_vfd_swmr_writer_end_of_tick() failed") done: - FUNC_LEAVE_NOAPI(ret_value) - } /* H5F__vfd_swmr_writer__wait_a_tick() */ herr_t diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index 321f85f..09188f6 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -824,19 +824,13 @@ error: return 1; } /* test_writer_create_open_flush() */ -/* Sleep for `tenths` tenths of a second. - * - * This routine may quietly perform a too-short sleep if an error occurs - * in nanosleep(2). - */ +/* Sleep for `tenths` tenths of a second */ static void decisleep(uint32_t tenths) { - struct timespec delay = {.tv_sec = tenths / 10, - .tv_nsec = tenths * 100 * 1000 * 1000}; + uint64_t nsec = tenths * 100 * 1000 * 1000; - while (HDnanosleep(&delay, &delay) == -1 && errno == EINTR) - ; // do nothing + H5_nanosleep(nsec); } -- cgit v0.12 From dea61b33b3904ae8db5ab3b2075a00822ae02c10 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 16:38:17 -0800 Subject: Removed Wnanosleep stub and adds Win32 code to H5_nanosleep() --- src/H5system.c | 40 ++++++++++++++++------------------------ src/H5win32defs.h | 2 -- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/H5system.c b/src/H5system.c index fff4c8c..c645105 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -1040,26 +1040,6 @@ Wflock(int fd, int operation) { return 0; } /* end Wflock() */ - - /*-------------------------------------------------------------------------- - * Function: Wnanosleep - * - * Purpose: Sleep for a given # of nanoseconds (Windows version) - * - * Return: SUCCEED/FAIL - * - * Programmer: Dana Robinson - * Fall 2016 - *-------------------------------------------------------------------------- - */ -int -Wnanosleep(const struct timespec *req, struct timespec *rem) -{ - /* XXX: Currently just a placeholder */ - return 0; - -} /* end Wnanosleep() */ - /*------------------------------------------------------------------------- * Function: Wllround, Wllroundf, Wlround, Wlroundf, Wround, Wroundf @@ -1439,15 +1419,13 @@ done: * * Purpose: Sleep for a given # of nanoseconds * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * October 01, 2016 + * Return: void *-------------------------------------------------------------------------- */ void H5_nanosleep(uint64_t nanosec) { +#ifndef H5_HAVE_WIN32_API const uint64_t nanosec_per_sec = 1000 * 1000 * 1000; struct timespec sleeptime; /* Struct to hold time to sleep */ @@ -1476,6 +1454,20 @@ H5_nanosleep(uint64_t nanosec) } FUNC_LEAVE_NOAPI_VOID +#else + DWORD dwMilliseconds = (DWORD)HDceil(nanosec / 1000.0); + DWORD ignore; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Windows can't sleep at a ns resolution. Best we can do is ~1 ms. We + * don't care about the return value since the second parameter + * (bAlertable) is FALSE, so it will always be zero. + */ + ignore = SleepEx(dwMilliseconds, FALSE); + + FUNC_LEAVE_NOAPI_VOID +#endif /* H5_HAVE_WIN32_API */ } /* end H5_nanosleep() */ #ifdef H5_HAVE_WIN32_API diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 8a73182..ab3acb9 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -86,7 +86,6 @@ typedef __int64 h5_stat_size_t; #define HDlseek(F,O,W) _lseeki64(F,O,W) #define HDlstat(S,B) _lstati64(S,B) #define HDmkdir(S,M) _mkdir(S) -#define HDnanosleep(N, O) Wnanosleep(N, O) #define HDoff_t __int64 /* Note that the variadic HDopen macro is using a VC++ extension @@ -169,7 +168,6 @@ extern "C" { H5_DLL char* Wgetlogin(void); H5_DLL int c99_snprintf(char* str, size_t size, const char* format, ...); H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap); - H5_DLL int Wnanosleep(const struct timespec *req, struct timespec *rem); H5_DLL herr_t H5_expand_windows_env_vars(char **env_var); H5_DLL const wchar_t *H5_get_utf16_str(const char *s); H5_DLL int Wopen_utf8(const char *path, int oflag, ...); -- cgit v0.12 From eb24fbe89c5040b531bd79dafd5a50552f434d50 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 16:49:40 -0800 Subject: Adds missing private VFD SWMR headers to CMake --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 038948c..a189f1b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -815,6 +815,8 @@ set (H5_PUBLIC_HEADERS set (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5private.h + ${HDF5_SRC_DIR}/H5queue.h + ${HDF5_SRC_DIR}/H5retry_private.h ${HDF5_SRC_DIR}/H5Apkg.h ${HDF5_SRC_DIR}/H5Aprivate.h -- cgit v0.12 From 94694f91a3cb723106d677c7e3e2ea3fe8c702e0 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Tue, 2 Mar 2021 17:22:22 -0800 Subject: Engineers around naked clock_gettime() calls This is a temporary solution, as not all POSIX platforms will have clock_gettime(). Further code fixes will be required. With this change, the main C library should compile on Windows. --- src/H5Fvfd_swmr.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 76748fe..0b0befd 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1502,10 +1502,14 @@ H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_shared_t *shared, FUNC_ENTER_STATIC /* Get current time in struct timespec */ - if ( HDclock_gettime(CLOCK_MONOTONIC, &curr) < 0 ) - - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, \ - "can't get time via clock_gettime") +#ifdef H5_HAVE_WIN32_API + if (timespec_get(&curr, TIME_UTC) != TIME_UTC) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via timespec_get"); +#else + if (HDclock_gettime(CLOCK_MONOTONIC, &curr) < 0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); + } +#endif /* Convert curr to nsecs */ curr_nsecs = curr.tv_sec * nanosecs_per_second + curr.tv_nsec; @@ -1952,10 +1956,14 @@ H5F_vfd_swmr_process_eot_queue(hbool_t entering_api) H5F_t *f = head->vfd_swmr_file; H5F_shared_t *shared = f->shared; +#ifdef H5_HAVE_WIN32_API + if(timespec_get(&now, TIME_UTC) != TIME_UTC) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via timespec_get"); +#else if(HDclock_gettime(CLOCK_MONOTONIC, &now) < 0) { - HGOTO_ERROR(H5E_FUNC, H5E_CANTGET, FAIL, - "can't get time via clock_gettime"); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); } +#endif if(timespeccmp(&now, &head->end_of_tick, <)) break; /* If the H5F_shared_t is labeled with a later EOT time than -- cgit v0.12 From b0ce859b2c2f3862df5c00c7c84f8abd777f3a62 Mon Sep 17 00:00:00 2001 From: vchoi Date: Thu, 4 Mar 2021 13:36:39 -0600 Subject: Add the two VFD SWMR demo programs to "examples" directory. Provide instructions on compiling and running the demos. --- examples/README | 27 ++ examples/credel.c | 484 ++++++++++++++++++++++++++++++++ examples/gaussians.c | 759 +++++++++++++++++++++++++++++++++++++++++++++++++++ examples/nbcompat.c | 17 ++ examples/nbcompat.h | 36 +++ 5 files changed, 1323 insertions(+) create mode 100644 examples/credel.c create mode 100644 examples/gaussians.c create mode 100644 examples/nbcompat.c create mode 100644 examples/nbcompat.h diff --git a/examples/README b/examples/README index e0a3364..4ab596d 100644 --- a/examples/README +++ b/examples/README @@ -15,3 +15,30 @@ installed. Compile scripts from other locations can be used by setting an environment variable prefix to the path of the directory containing the bin directory with the compile scripts h5cc, h5fc, etc. For example, export prefix=/usr/local/hdf5 to use h5cc, h5fc, etc. in /usr/local/hdf5/bin. + +*************************************************************************************** +Instruction for compiling and running the two VFD SWMR demo programs in this directory: + +credel.c: +========= +To compile: + h5cc -o credel credel.c nbcompat.c + +To run: + ./credel -v (on one window) + h5ls --vfd=swmr --poll=100 -r -d ./credel.h5 (on another window) + +vfd_swmr_gaussians.c +==================== +To compile: + h5cc -o gaussians ./gaussians.c ./nbcompat.c -lcurses +To link as writer: + ln -s gaussians wgaussians +To link as reader: + ln -s gaussians rgaussians + +To run standalone: + ./gaussians +To run as writer and reader: + ./wgaussians (on one window) + ./rgaussians (on another window) diff --git a/examples/credel.c b/examples/credel.c new file mode 100644 index 0000000..218baeb --- /dev/null +++ b/examples/credel.c @@ -0,0 +1,484 @@ +#include +#include +#include +#include /* basename(3) */ +#include +#include +#include +#include +#include /* struct timespec, nanosleep */ +#include /* getopt, PATH_MAX, ... */ + +#include "hdf5.h" +#include "nbcompat.h" + +#define DATAROWS 1 +#define DATACOLS 10 +static const hsize_t dims[2] = {DATAROWS, DATACOLS}; +static const hsize_t chunk_dims[2] = {1, 1}; +static volatile sig_atomic_t unbroken = 1; + +typedef struct { + uint64_t created, deleted; +} stats_pair_t; + +typedef struct { + stats_pair_t datasets, groups; + uint64_t iterations; +} stats_t; + +typedef struct { + hid_t dataset[4], dataspace, dapl, dcpl, file, group[2]; + char output_file[PATH_MAX]; + char progname[PATH_MAX]; + struct timespec update_interval; + int verbose; + bool oneshot; + bool print_stats; + bool use_vfd_swmr; + uint64_t iterations_limit; + stats_t stats; +} state_t; + +#define ALL_HID_INITIALIZER (state_t){ \ + .dataspace = H5I_INVALID_HID \ + , .file = H5I_INVALID_HID \ + , .verbose = 0 \ + , .oneshot = false \ + , .use_vfd_swmr = true \ + , .print_stats = false \ + , .iterations_limit = UINT64_MAX \ + , .output_file = "" \ + , .update_interval = (struct timespec){ \ + .tv_sec = 0 \ + , .tv_nsec = 1000000000UL / 10 /* 1/10 second */} \ + , .stats = {{0, 0}, {0, 0}}} + +static void state_init(state_t *, int, char **); + +static void +write_dataset(state_t *s, int didx) +{ + const int ndatasets = __arraycount(s->dataset); + hid_t ds; + int32_t data[DATAROWS][DATACOLS]; + herr_t status; + unsigned int i, j; + + for (i = 0; i < __arraycount(data); i++) { + for (j = 0; j < __arraycount(data[i]); j++) { + int k = (didx + j + i) % __arraycount(data[i]); + data[i][j] = (0 <= k && k < 3) ? 1 : 0; + if (s->verbose > 1) + fprintf(stderr, " %" PRId32, data[i][j]); + } + if (s->verbose > 1) + fprintf(stderr, "\n"); + } + + ds = s->dataset[didx % ndatasets]; + status = H5Dwrite(ds, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, + H5P_DEFAULT, data); + + if (status < 0) + errx(EXIT_FAILURE, "H5Dwrite failed"); + + if (H5Dflush(ds) < 0) + errx(EXIT_FAILURE, "H5Dflush failed"); +} + +static void +usage(const char *progname) +{ + fprintf(stderr, "usage: %s [-u milliseconds]\n" + "\n" + "-o: oneshot mode, perform one iteration, wait for a signal, " + "then quit.\n" + "-s: print statistics at end\n" + "-S: disable VFD SWMR mode\n" + "-u ms: milliseconds interval between updates to %s.h5\n" + "-v: verbose mode, mention creation/deletion; -vv: print data\n" + "\n", + progname, progname); + exit(EXIT_FAILURE); +} + +static void +print_stats(stats_t *s) +{ + printf("%10" PRIu64 " groups created\n", s->groups.created); + printf("%10" PRIu64 " groups deleted\n", s->groups.deleted); + printf("%10" PRIu64 " datasets created\n", s->datasets.created); + printf("%10" PRIu64 " datasets deleted\n", s->datasets.deleted); + printf("%10" PRIu64 " iterations\n", s->iterations); +} + +static void +state_init(state_t *s, int argc, char **argv) +{ + int ch, i, rc; + char tfile[PATH_MAX]; + char *end; + unsigned long millis; + uintmax_t niters; + + *s = ALL_HID_INITIALIZER; + strlcpy(tfile, argv[0], sizeof(tfile)); + strlcpy(s->progname, basename(tfile), sizeof(s->progname)); + while ((ch = getopt(argc, argv, "n:ou:sSv")) != -1) { + switch (ch) { + case 'n': + niters = strtoumax(optarg, &end, 0); + if (niters == UINTMAX_MAX && errno == ERANGE) { + err(EXIT_FAILURE, "option -%c argument \"%s\"", + ch, optarg); + } else if (*end != '\0') { + errx(EXIT_FAILURE, + "garbage after -%c argument \"%s\"", ch, + optarg); + } + s->iterations_limit = niters; + break; + case 'o': + s->oneshot = true; + break; + case 's': + s->print_stats = true; + break; + case 'S': + s->use_vfd_swmr = false; + break; + case 'u': + errno = 0; + millis = strtoul(optarg, &end, 0); + if (millis == ULONG_MAX && errno == ERANGE) { + err(EXIT_FAILURE, "option -%c argument \"%s\"", + ch, optarg); + } else if (*end != '\0') { + errx(EXIT_FAILURE, + "garbage after -%c argument \"%s\"", ch, + optarg); + } + s->update_interval.tv_sec = millis / 1000UL; + s->update_interval.tv_nsec = (millis * 1000000UL) % 1000000000UL; + warnx("%lu milliseconds between updates", millis); + break; + case 'v': + s->verbose++; + break; + case '?': + default: + usage(s->progname); + } + } + argc -= optind; + argv += optind; + + for (i = 0; i < __arraycount(s->dataset); i++) + s->dataset[i] = H5I_INVALID_HID; + + for (i = 0; i < __arraycount(s->group); i++) + s->group[i] = H5I_INVALID_HID; + + rc = snprintf(s->output_file, sizeof(s->output_file), "%s.h5", s->progname); + if (rc == -1 || rc >= sizeof(s->output_file)) + errx(EXIT_FAILURE, "output filename was truncated"); +} + +static void +delete_group(state_t *s, const int64_t gidx) +{ + hid_t g; + const int ngroups = __arraycount(s->group); + char gname[32]; + + assert(0 <= gidx); + + snprintf(gname, sizeof(gname), "/group-%" PRId64, gidx); + g = s->group[gidx % ngroups]; + + if (H5Ldelete(s->file, gname, H5P_DEFAULT) < 0) { + errx(EXIT_FAILURE, "%s: H5Ldelete(, \"%s\", ) failed", + __func__, gname); + } + + if (H5Gclose(g) < 0) + errx(EXIT_FAILURE, "H5Gclose failed"); + + if (s->verbose > 0) + fprintf(stderr, "Deleted group %s\n", gname); + + s->group[gidx % ngroups] = H5I_INVALID_HID; + s->stats.groups.deleted++; +} + +static void +create_group(state_t *s, const int64_t gidx) +{ + const int ngroups = __arraycount(s->group); + hid_t g; + char gname[32]; + + assert(0 <= gidx); + assert(s->group[gidx % ngroups] == H5I_INVALID_HID); + + snprintf(gname, sizeof(gname), "/group-%" PRId64, gidx); + g = H5Gcreate(s->file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (g < 0) + errx(EXIT_FAILURE, "H5Gcreate failed"); + + if (s->verbose > 0) + fprintf(stderr, "Created group %s\n", gname); + s->group[gidx % ngroups] = g; + s->stats.groups.created++; +} + +static void +delete_dataset(state_t *s, const int64_t didx) +{ + const int ndatasets = __arraycount(s->dataset); + char dname[32]; + const int64_t gidx = didx / 2; + + assert(0 <= gidx && 0 <= didx); + + snprintf(dname, sizeof(dname), "/group-%" PRId64 "/dataset-%" PRId64, + gidx, didx); + if (H5Ldelete(s->file, dname, H5P_DEFAULT) < 0) { + errx(EXIT_FAILURE, "%s: H5Ldelete(, \"%s\", ) failed", + __func__, dname); + } + + if (s->verbose > 0) + fprintf(stderr, "Deleted dataset %s\n", dname); +#if 1 + const hid_t ds = s->dataset[didx % ndatasets]; + if (H5Dclose(ds) < 0) + errx(EXIT_FAILURE, "H5Dclose failed"); +#endif + s->dataset[didx % ndatasets] = H5I_INVALID_HID; + s->stats.datasets.deleted++; +} + +static void +create_dataset(state_t *s, const int64_t didx) +{ + const int ndatasets = __arraycount(s->dataset); + char dname[32]; + const int64_t gidx = didx / 2; + hid_t ds; + + assert(0 <= gidx && 0 <= didx); + assert(s->dataset[didx % ndatasets] == H5I_INVALID_HID); + + s->dataspace = H5Screate_simple(__arraycount(dims), dims, NULL); + + if (s->dataspace < 0) + errx(EXIT_FAILURE, "H5Screate_simple failed"); + + snprintf(dname, sizeof(dname), "/group-%" PRId64 "/dataset-%" PRId64, + gidx, didx); + ds = H5Dcreate2(s->file, dname, + H5T_STD_I32BE, s->dataspace, + H5P_DEFAULT, s->dcpl, s->dapl); + + if (H5Sclose(s->dataspace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); + + s->dataspace = H5I_INVALID_HID; + + if (ds < 0) + errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); + + if (s->verbose > 0) + fprintf(stderr, "Created dataset %s\n", dname); + s->dataset[didx % ndatasets] = ds; + s->stats.datasets.created++; +} + +static void +create_and_write_dataset(state_t *s, const int64_t didx) +{ +#if 0 + const int64_t gidx = didx / 2; + const int ngroups = __arraycount(s->group); + const hid_t g = s->group[gidx % ngroups]; + + if (H5Odisable_mdc_flushes(g) < 0) + err(EXIT_FAILURE, "H5Odisable_mdc_flushes failed"); +#endif + + create_dataset(s, didx); + write_dataset(s, didx); + +#if 0 + if (H5Oenable_mdc_flushes(g) < 0) + err(EXIT_FAILURE, "H5Oenable_mdc_flushes failed"); +#endif +} + +static void +handle_signal(int signo) +{ + char msg[] = "Handling signal\n"; + write(STDERR_FILENO, msg, sizeof(msg) - 1); + unbroken = 0; +} + +static void +disestablish_handler(const struct sigaction *osa) +{ + if (sigaction(SIGINT, osa, NULL) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +static void +establish_handler(struct sigaction *osa) +{ + struct sigaction sa; + + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = handle_signal; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, osa) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +int +main(int argc, char **argv) +{ + hid_t fapl, fcpl; + struct sigaction osa; + state_t storage; + state_t *s = &storage; + int64_t i; + H5F_vfd_swmr_config_t config; + + memset(&config, '\0', sizeof(config)); + + state_init(s, argc, argv); + + fapl = H5Pcreate(H5P_FILE_ACCESS); + if (fapl < 0) { + errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", + __func__, __LINE__); + } + + fcpl = H5Pcreate(H5P_FILE_CREATE); + if (fcpl < 0) { + errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", + __func__, __LINE__); + } + + config.version = H5F__CURR_VFD_SWMR_CONFIG_VERSION; + config.tick_len = 4; + config.max_lag = 5; +#if 0 /* raw-data flushing is not implemented */ + config.flush_raw_data = true; +#endif + config.writer = true; + config.md_pages_reserved = 128; + strlcpy(config.md_file_path, "./my_md_file", + sizeof(config.md_file_path)); + + /* Enable page buffering */ + if (H5Pset_page_buffer_size(fapl, 4096, 100, 0) < 0) + errx(EXIT_FAILURE, "H5Pset_page_buffer_size failed"); + + /* Enable VFD SWMR configuration */ + if (s->use_vfd_swmr && H5Pset_vfd_swmr_config(fapl, &config) < 0) + errx(EXIT_FAILURE, "H5Pset_vfd_swmr_config failed"); + + /* Set file space strategy to paged aggregation in fcpl. + * Page buffering *requires* this strategy. + * + * I set the free-space threshold to 1GB so that deleted + * datasets are not recycled. + */ + if (H5Pset_file_space_strategy(fcpl, + H5F_FSPACE_STRATEGY_PAGE, false, 1024 * 1024 * 1024) < 0) + errx(EXIT_FAILURE, "H5Pset_file_space_strategy failed"); + + s->file = H5Fcreate(s->output_file, H5F_ACC_TRUNC, fcpl, fapl); + + H5Pclose(fapl); + + if (s->file < 0) + errx(EXIT_FAILURE, "H5Fcreate failed"); + + if ((s->dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", + __func__, __LINE__); + } + if ((s->dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", + __func__, __LINE__); + } + if (H5Pset_chunk(s->dcpl, 2, chunk_dims) < 0) + errx(EXIT_FAILURE, "H5Pset_chunk failed"); + if (H5Pset_chunk_cache(s->dapl, H5D_CHUNK_CACHE_NSLOTS_DEFAULT, 0, + H5D_CHUNK_CACHE_W0_DEFAULT) < 0) + errx(EXIT_FAILURE, "H5Pset_chunk_cache failed"); + + establish_handler(&osa); + + for (i = 0; i < 4; i++) { + s->stats.iterations++; + if (i % 2 == 0) + create_group(s, i / 2); + create_and_write_dataset(s, i); + } + + for (i = 5; unbroken; i += 2) { + delete_dataset(s, i - 5); + delete_dataset(s, i - 4); + delete_group(s, (i - 4) / 2); + create_group(s, i / 2); + create_and_write_dataset(s, i - 1); + create_and_write_dataset(s, i); + if (s->oneshot || ++s->stats.iterations >= s->iterations_limit) + break; + nanosleep(&s->update_interval, NULL); + } + + if (s->oneshot) { + sigset_t mask; + sigemptyset(&mask); + H5Fvfd_swmr_end_tick(s->file); + (void)sigsuspend(&mask); + } +#if 0 + fprintf(stderr, "Interrupted. Cleaning up.\n"); + + int j; + for (--i, j = 0; j < 4; j++, --i) { + if (i % 2 == 1) { + delete_dataset(s, i - 1); + delete_dataset(s, i); + delete_group(s, i / 2); + } + } + + for (j = 0; j < 4; j++) { + assert(s->dataset[j] == H5I_INVALID_HID); + assert(s->group[j / 2] == H5I_INVALID_HID); + } +#endif + + if (s->print_stats) + print_stats(&s->stats); + + if (H5Fclose(s->file) < 0) + errx(EXIT_FAILURE, "H5Fclose failed"); + + if (H5Pclose(s->dapl) < 0) + errx(EXIT_FAILURE, "H5Pclose failed"); + + if (H5Pclose(s->dcpl) < 0) + errx(EXIT_FAILURE, "H5Pclose failed"); + + disestablish_handler(&osa); + + return EXIT_SUCCESS; +} diff --git a/examples/gaussians.c b/examples/gaussians.c new file mode 100644 index 0000000..0ceeb8b --- /dev/null +++ b/examples/gaussians.c @@ -0,0 +1,759 @@ +#include +#include +#include +#include +#include /* basename(3) */ +#include /* expf(3) */ +#include /* setlocale(3) */ +#include +#include +#include +#include +#include /* struct timespec, nanosleep(2), time(3), + * clock_gettime(2) + */ +#include /* getopt, PATH_MAX, ... */ + +#include /* for MIN(a, b) */ + +#include "hdf5.h" +#include "nbcompat.h" + +#define SWMR_TICK_LEN 4 /* in 100 ms */ + +typedef enum { + STANDALONE = 0 + , READ = 1 + , WRITE = 2 +} personality_t; + +typedef enum { + TOP = 0 + , BOTTOM + , LEFT + , RIGHT + , NSIDES +} side_t; + +typedef struct { + bool side[NSIDES]; +} inside_t; + +typedef struct { + float x, y; +} vec_t; + +#define RANK 3 +#define ROWS 20 +#define COLS 40 +static const hsize_t original_dims[RANK] = {0, ROWS, COLS}; +static const hsize_t max_dims[RANK] = {H5S_UNLIMITED, ROWS, COLS}; +static const hsize_t frame_dims[RANK] = {1, ROWS, COLS}; +static const hsize_t *chunk_dims = frame_dims; +static volatile sig_atomic_t unbroken = 1; + +typedef struct { + /* main-loop statistics */ + uint64_t max_elapsed_ns, min_elapsed_ns, total_elapsed_ns; + uint64_t total_loops; + hid_t dataset, memspace, dcpl, file, group; + char output_file[PATH_MAX]; + char progname[PATH_MAX]; + struct timespec update_interval; + bool fuzz; + bool constantrate; + unsigned int partstep; +} state_t; + +#define ALL_HID_INITIALIZER (state_t){ \ + .total_elapsed_ns = 0 \ + , .total_loops = 0 \ + , .min_elapsed_ns = UINT64_MAX \ + , .max_elapsed_ns = 0 \ + , .memspace = H5I_INVALID_HID \ + , .file = H5I_INVALID_HID \ + , .constantrate = false \ + , .partstep = 0 \ + , .output_file = "" \ + , .update_interval = (struct timespec){ \ + .tv_sec = 0 \ + , .tv_nsec = 1000000000UL / 30 /* 1/30 second */}} + +static void state_init(state_t *, int, char **); + +static void +usage(const char *progname) +{ + fprintf(stderr, "usage: %s [-u milliseconds]\n" + "\n" + "-c: increase the frame number continously (reader mode)\n" + "-f: add \"fuzz\" (linear noise) to the data (writer mode)\n" + "-u ms: milliseconds interval between updates to %s.h5\n" + "\n", + progname, progname); + exit(EXIT_FAILURE); +} + +static void +state_init(state_t *s, int argc, char **argv) +{ + int ch; + char tfile[PATH_MAX]; + char *end; + unsigned long millis; + + *s = ALL_HID_INITIALIZER; + strlcpy(tfile, argv[0], sizeof(tfile)); + strlcpy(s->progname, basename(tfile), sizeof(s->progname)); + + while ((ch = getopt(argc, argv, "cfu:")) != -1) { + switch (ch) { + case 'c': + s->constantrate = true; + break; + case 'f': + s->fuzz = true; + 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 = millis / 1000UL; + s->update_interval.tv_nsec = + (millis * 1000000UL) % 1000000000UL; + warnx("%lu milliseconds between updates", millis); + break; + case '?': + default: + usage(s->progname); + } + } + argc -= optind; + argv += optind; + + s->dataset = H5I_INVALID_HID; + s->group = H5I_INVALID_HID; + + s->memspace = H5Screate_simple(RANK, frame_dims, NULL); + + if (s->memspace < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", + __func__, __LINE__); + } + + const int nprinted = snprintf(s->output_file, sizeof(s->output_file), + "%s.h5", s->progname); + if (nprinted < 0 || nprinted >= sizeof(s->output_file)) { + errx(EXIT_FAILURE, "%s.%d: output filename truncated.", + __func__, __LINE__); + } +} + +static void +matrix_read(state_t *s, int *framenop, float mat[ROWS][COLS]) +{ + hid_t ds, filespace; + herr_t status; + hsize_t dims[RANK]; + + ds = s->dataset; + + if (H5Drefresh(ds) < 0) + errx(EXIT_FAILURE, "H5Drefresh failed"); + + filespace = H5Dget_space(ds); + + if (H5Sget_simple_extent_dims(filespace, dims, NULL) < 0) + errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); + + if (dims[1] != original_dims[1] || dims[2] != original_dims[2]) { + errx(EXIT_FAILURE, "Unexpected dimensions N x %ju x %ju", + (uintmax_t)dims[1], (uintmax_t)dims[2]); + } + + const uint64_t update_ms = timespec2ns(&s->update_interval) / 1000000; + const uint32_t tick_ms = SWMR_TICK_LEN * 100; + const uint64_t updates_per_tick = (tick_ms + update_ms - 1) / update_ms; + const hssize_t hang_back = 2 * updates_per_tick; + const int frameno = *framenop; + + const int lead = frameno + hang_back - dims[0]; + if (s->constantrate) { + *framenop = frameno + 1; + } else if (lead > hang_back * 2) { + if (++s->partstep % 3 == 0) + *framenop = frameno + 1; + } else if (lead > 0) { + if (++s->partstep % 2 == 0) + *framenop = frameno + 1; + } else if (lead == 0) { + *framenop = frameno + 1; + } else if (lead < -hang_back * 2) { + /* We're way behind, so jump close to the front. */ + *framenop = dims[0] - hang_back; + } else /* lead < 0 */ { + *framenop = frameno + 1; + if (++s->partstep % 2 == 0) + *framenop = frameno + 2; + } + +#if 0 + if (!s->constantrate && (lead < -2 || 2 < lead)) { + int gain = 31250 / 4; + const struct timespec prior_integral = s->update_integral; + struct timespec current_interval; + if (lead > 0) + gain *= 2; + struct timespec adjustment = (struct timespec){.tv_sec = 0, + .tv_nsec = gain * MAX(MIN(4, lead), -4)}; + /* XXX clamp it XXX */ + timespecadd(&s->update_integral, + &adjustment, &s->update_integral); + timespecadd(&s->update_integral, + &s->update_interval, ¤t_interval); + if (timespeccmp(¤t_interval, &s->min_interval, <=)) + s->update_integral = prior_integral; + } +#endif + + if (frameno >= dims[0]) { + int i, j; + for (i = 0; i < ROWS; i++) { + for (j = 0; j < COLS; j++) + mat[i][j] = ((i + j) % 2 == 0) ? 0. : 1.; + } + return; + } + + hsize_t offset[RANK] = {frameno, 0, 0}; + + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, + frame_dims, NULL) < 0) + errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); + + status = H5Dread(ds, H5T_NATIVE_FLOAT, s->memspace, filespace, + H5P_DEFAULT, mat); + + if (status < 0) + errx(EXIT_FAILURE, "H5Dread failed"); + + if (H5Sclose(filespace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); +} + +static void +matrix_write(state_t *s, int frameno, float mat[ROWS][COLS]) +{ + hid_t ds, filespace; + herr_t status; + hsize_t size[RANK] = {frameno + 1, ROWS, COLS}; + hsize_t offset[RANK] = {frameno, 0, 0}; + + ds = s->dataset; + + if (H5Dset_extent(ds, size) < 0) + errx(EXIT_FAILURE, "H5Dset_extent failed"); + + filespace = H5Dget_space(ds); + + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, + frame_dims, NULL) < 0) + errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); + + status = H5Dwrite(ds, H5T_NATIVE_FLOAT, s->memspace, filespace, + H5P_DEFAULT, mat); + + if (status < 0) + errx(EXIT_FAILURE, "H5Dwrite failed"); + + if (H5Sclose(filespace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); + + if (H5Dflush(ds) < 0) + errx(EXIT_FAILURE, "H5Dflush failed"); +} + +static void +open_group(state_t *s) +{ + hid_t g; + const char *gname = "/group-0"; + + assert(s->group == H5I_INVALID_HID); + + g = H5Gopen(s->file, gname, H5P_DEFAULT); + + if (g < 0) + errx(EXIT_FAILURE, "H5Gcreate failed"); + + fprintf(stderr, "Opened group %s\n", gname); + s->group = g; +} + +static void +create_group(state_t *s) +{ + hid_t g; + const char *gname = "/group-0"; + + assert(s->group == H5I_INVALID_HID); + + g = H5Gcreate(s->file, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (g < 0) + errx(EXIT_FAILURE, "H5Gcreate failed"); + + s->group = g; +} + +static void +open_dataset(state_t *s) +{ + const char *dname = "/group-0/dataset-0"; + hid_t ds; + hid_t filespace; + hid_t ty; + hsize_t dims[RANK], maxdims[RANK]; + + assert(s->dataset == H5I_INVALID_HID); + + ds = H5Dopen(s->file, dname, H5P_DEFAULT); + + if (ds < 0) + errx(EXIT_FAILURE, "H5Dopen(, \"%s\", ) failed", dname); + + if ((ty = H5Dget_type(ds)) < 0) + errx(EXIT_FAILURE, "H5Dget_type failed"); + + if (H5Tequal(ty, H5T_IEEE_F32BE) <= 0) + errx(EXIT_FAILURE, "Unexpected data type"); + + if ((filespace = H5Dget_space(ds)) < 0) + errx(EXIT_FAILURE, "H5Dget_space failed"); + + if (H5Sget_simple_extent_ndims(filespace) != RANK) + errx(EXIT_FAILURE, "Unexpected rank"); + + if (H5Sget_simple_extent_dims(filespace, dims, maxdims) < 0) + errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); + + if (dims[1] != original_dims[1] || dims[2] != original_dims[2]) { + errx(EXIT_FAILURE, "Unexpected dimensions ? x %ju x %ju", + (uintmax_t)dims[1], (uintmax_t)dims[2]); + } + + if (maxdims[1] != original_dims[1] || maxdims[2] != original_dims[2]) { + errx(EXIT_FAILURE, + "Unexpected maximum dimensions ? x %ju x %ju", + (uintmax_t)dims[1], (uintmax_t)dims[2]); + } + + fprintf(stderr, "Opened dataset %s\n", dname); + s->dataset = ds; +} + +static void +create_dataset(state_t *s) +{ + const char *dname = "/group-0/dataset-0"; + hid_t ds; + hid_t filespace; + + assert(s->dataset == H5I_INVALID_HID); + + filespace = H5Screate_simple(__arraycount(original_dims), original_dims, + max_dims); + + if (filespace < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", + __func__, __LINE__); + } + + if ((s->dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { + errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", + __func__, __LINE__); + } + + if (H5Pset_chunk(s->dcpl, RANK, chunk_dims) < 0) + errx(EXIT_FAILURE, "H5Pset_chunk failed"); + + ds = H5Dcreate2(s->file, dname, H5T_IEEE_F32BE, filespace, + H5P_DEFAULT, s->dcpl, H5P_DEFAULT); + + if (H5Sclose(filespace) < 0) + errx(EXIT_FAILURE, "H5Sclose failed"); + + filespace = H5I_INVALID_HID; + + if (ds < 0) + errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); + + s->dataset = ds; +} + +static void +handle_signal(int signo) +{ + unbroken = 0; +} + +static void +disestablish_handler(const struct sigaction *osa) +{ + if (sigaction(SIGINT, osa, NULL) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +static void +establish_handler(struct sigaction *osa) +{ + struct sigaction sa; + + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = handle_signal; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGINT, &sa, osa) == -1) + err(EXIT_FAILURE, "%s: sigaction", __func__); +} + +static void +step(vec_t *center, vec_t *direction, float steplen, bool *recursed) +{ + static const float top = 0., bottom = (float)COLS, + left = 0., right = (float)ROWS; + struct { + bool top, bottom, left, right; + } bounce = {false, false, false, false}; + float xback, yback; + vec_t before = *center; + vec_t after = (vec_t){.x = before.x + direction->x * steplen, + .y = before.y + direction->y * steplen}; + + if (before.x < right && after.x >= right) { + xback = (right - before.x) / (after.x - before.x); + bounce.right = true; + } else if (before.x > left && after.x <= left) { + xback = (before.x - left) / (before.x - after.x); + bounce.left = true; + } else + xback = 0.; + + if (before.y < bottom && after.y >= bottom) { + yback = (bottom - before.y) / (after.y - before.y); + bounce.bottom = true; + } else if (before.y > top && after.y <= top) { + yback = (before.y - top) / (before.y - after.y); + bounce.top = true; + } else + yback = 0.; + + /* I shorten the step length until a corner crossing becomes + * a side crossing. + */ + if ((bounce.top && bounce.right) || + (bounce.right && bounce.bottom) || + (bounce.bottom && bounce.left) || + (bounce.left && bounce.top)) { + + float newsteplen = steplen * 2 / 3; + if (recursed != NULL) + *recursed = true; + step(center, direction, newsteplen, NULL); + step(center, direction, steplen - newsteplen, NULL); + } + if (bounce.right || bounce.left) { + after.x = before.x + direction->x * (2 * xback - 1) * steplen; + direction->x = -direction->x; + } + if (bounce.top || bounce.bottom) { + after.y = before.y + direction->y * (2 * yback - 1) * steplen; + direction->y = -direction->y; + } + *center = after; +} + +static float +gaussian(float x, float y, float r) +{ + return expf(-(x * x + y * y) / (r * r)); +} + +int +stepno(float v) +{ + if (v < 1. / 8.) + return 0; + if (v < 3. / 8.) + return 1; + if (v < 7 / 8.) + return 2; + + return 3; +} + +static void +draw_border(WINDOW *w) +{ + wborder(w, 0, 0, 0, 0, 0, 0, 0, 0); +} + +static void +matrix_draw(WINDOW *w, float mat[ROWS][COLS]) +{ + int ch, i, j; + static char steps[] = " .oO"; + + wclear(w); + draw_border(w); + for (i = 0; i < ROWS; i++) { + wmove(w, 1 + i, 1); + for (j = 0; j < COLS; j++) { + ch = steps[stepno(mat[i][j])]; + waddch(w, ch); + } + } + + wnoutrefresh(w); +} + +static void +matrix_compute(vec_t *center, size_t ncenters, float mat[ROWS][COLS]) +{ + int i, j, k; + float radius = 4; + + for (i = 0; i < ROWS; i++) { + for (j = 0; j < COLS; j++) { + mat[i][j] = 0.; + for (k = 0; k < ncenters; k++) { + mat[i][j] += gaussian(i - center[k].x, + j - center[k].y, radius); + } + } + } +} + +static void +move_centers(vec_t *center, vec_t *direction, size_t ncenters) +{ + const float steplen = .01; + int k; + bool recursed[2] = {false, false}; + + for (k = 0; k < ncenters; k++) { + recursed[k] = false; + step(¢er[k], &direction[k], steplen, &recursed[k]); + } +} + +static void +matrix_open(state_t *s, bool rw) +{ + const char *func; + hid_t fapl, fcpl; + H5F_vfd_swmr_config_t config; + + fapl = H5Pcreate(H5P_FILE_ACCESS); + if (fapl < 0) { + errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", + __func__, __LINE__); + } + + fcpl = H5Pcreate(H5P_FILE_CREATE); + if (fcpl < 0) { + errx(EXIT_FAILURE, "%s.%d H5Pcreate failed", + __func__, __LINE__); + } + + memset(&config, '\0', sizeof(config)); + + config.version = H5F__CURR_VFD_SWMR_CONFIG_VERSION; + config.tick_len = SWMR_TICK_LEN; + config.max_lag = 5; + config.writer = rw; + config.md_pages_reserved = 128; + +#if 0 /* raw-data flushing is not implemented; default open-tries is ok */ + config.flush_raw_data = true; + config.md_open_tries = 1; +#endif + + strlcpy(config.md_file_path, "./my_md_file", sizeof(config.md_file_path)); + + /* Enable page buffering */ + if (H5Pset_page_buffer_size(fapl, 4096, 100, 0) < 0) + errx(EXIT_FAILURE, "H5Pset_page_buffer_size failed"); + + /* Enable VFD SWMR configuration */ + if (H5Pset_vfd_swmr_config(fapl, &config) < 0) + errx(EXIT_FAILURE, "H5Pset_vfd_swmr_config failed"); + + /* Set file space strategy to paged aggregation in fcpl. + * Page buffering *requires* this strategy. + * + * I set the free-space threshold to 1GB so that deleted + * datasets are not recycled. + */ + if (H5Pset_file_space_strategy(fcpl, + H5F_FSPACE_STRATEGY_PAGE, false, 1024 * 1024 * 1024) < 0) + errx(EXIT_FAILURE, "H5Pset_file_space_strategy failed"); + + if (rw) { + s->file = H5Fcreate("gaussians.h5", H5F_ACC_TRUNC, fcpl, fapl); + func = "H5Fcreate"; + } else { + s->file = H5Fopen("gaussians.h5", H5F_ACC_RDONLY, fapl); + func = "H5Fopen"; + } + + H5Pclose(fapl); + + if (s->file < 0) + errx(EXIT_FAILURE, "%s failed", func); +} + +static void +fuzz(float mat[ROWS][COLS]) +{ + int i, j; + + for (i = 0; i < ROWS; i++) { + for (j = 0; j < COLS; j++) { + mat[i][j] += (float)random() / RAND_MAX * (9. / 64.); + } + } +} + +int +main(int argc, char **argv) +{ + char buf[32]; + float mat[ROWS][COLS]; + int frameno; + vec_t center[2] = {{.x = .5, .y = .5}, + {.x = ROWS - .5, .y = COLS - .5}}; + vec_t direction[2] = {{.x = 3, .y = 7}, {.x = 43, .y = 41}}; + struct sigaction osa; + WINDOW *topw = NULL, *w = NULL; + personality_t personality; + state_t s; + + srandom((unsigned int)time(NULL)); + + setlocale(LC_ALL, ""); + + state_init(&s, argc, argv); + + switch (s.progname[0]) { + case 'r': + personality = READ; + break; + case 'w': + personality = WRITE; + break; + default: + personality = STANDALONE; + break; + } + establish_handler(&osa); + + switch (personality) { + case WRITE: + matrix_open(&s, true); + create_group(&s); + create_dataset(&s); + break; + case READ: + matrix_open(&s, false); + open_group(&s); + open_dataset(&s); + break; + default: + break; + } + + if ((topw = initscr()) == NULL) + errx(EXIT_FAILURE, "initscr failed"); + else if ((w = subwin(topw, ROWS + 2, COLS + 2, 0, 0)) == NULL) + errx(EXIT_FAILURE, "subwin failed"); + + for (frameno = 0; unbroken; ) { + struct timespec elapsed, start, stop; + uint64_t elapsed_ns; + clock_gettime(CLOCK_MONOTONIC, &start); + + switch (personality) { + case READ: + matrix_read(&s, &frameno, mat); + break; + case WRITE: + case STANDALONE: + matrix_compute(center, __arraycount(center), mat); + if (s.fuzz) + fuzz(mat); + break; + } + switch (personality) { + case READ: + case STANDALONE: + matrix_draw(w, mat); +#if 0 + wmove(topw, ROWS + 3, 0); + waddstr(topw, "\"Don't cross the streams.\""); +#endif + break; + case WRITE: + matrix_write(&s, frameno, mat); + break; + } + + snprintf(buf, sizeof(buf), "Frame %d.", frameno); + wmove(topw, ROWS + 2, 0); + waddstr(topw, buf); + snprintf(buf, sizeof(buf), "Rate %lld/s.", + 1000000000ULL / timespec2ns(&s.update_interval)); + wmove(topw, ROWS + 2, COLS + 2 - strlen(buf)); + waddstr(topw, buf); + wnoutrefresh(topw); + doupdate(); + + nanosleep(&s.update_interval, NULL); + + switch (personality) { + case STANDALONE: + case WRITE: + move_centers(center, direction, __arraycount(center)); + frameno++; + break; + case READ: + break; + } + clock_gettime(CLOCK_MONOTONIC, &stop); + + timespecsub(&stop, &start, &elapsed); + elapsed_ns = timespec2ns(&elapsed); + + if (elapsed_ns < s.min_elapsed_ns) + s.min_elapsed_ns = elapsed_ns; + if (elapsed_ns > s.max_elapsed_ns) + s.max_elapsed_ns = elapsed_ns; + s.total_elapsed_ns += elapsed_ns; + s.total_loops++; + } + endwin(); + fprintf(stderr, "Iteration stats:\n"); + fprintf(stderr, "min. elapsed %" PRIu64 " ms\n", + s.min_elapsed_ns / 1000000); + fprintf(stderr, "max. elapsed %" PRIu64 " ms\n", + s.max_elapsed_ns / 1000000); + fprintf(stderr, "avg. elapsed %.3f ms\n", + (double)s.total_elapsed_ns / s.total_loops / 1000000); + disestablish_handler(&osa); + return EXIT_SUCCESS; +} diff --git a/examples/nbcompat.c b/examples/nbcompat.c new file mode 100644 index 0000000..03e477f --- /dev/null +++ b/examples/nbcompat.c @@ -0,0 +1,17 @@ +#include "nbcompat.h" + +size_t +strlcpy(char *dst, const char *src, size_t size) +{ + char *d; + const char *s; + + for (d = dst, s = src; (s - src) < size; d++, s++) { + *d = *s; + if (*s == '\0') + return s - src; + } + + dst[size - 1] = '\0'; + return size; +} diff --git a/examples/nbcompat.h b/examples/nbcompat.h new file mode 100644 index 0000000..98f8c7d --- /dev/null +++ b/examples/nbcompat.h @@ -0,0 +1,36 @@ +#ifndef NB_COMPAT_H +#define NB_COMPAT_H + +#include /* for size_t */ + +#ifndef __arraycount +#define __arraycount(__a) (sizeof(__a) / sizeof((__a)[0])) +#endif + +size_t strlcpy(char *, const char *, size_t); + +#define timespeccmp(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +#define timespecadd(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ + if ((vsp)->tv_nsec >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while (/* CONSTCOND */ 0) +#define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while (/* CONSTCOND */ 0) +#define timespec2ns(x) (((uint64_t)(x)->tv_sec) * 1000000000L + (x)->tv_nsec) + +#endif /* NB_COMPAT_H */ -- cgit v0.12