diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | m4/ax_with_curses.m4 | 571 | ||||
-rw-r--r-- | test/Makefile.am | 16 | ||||
-rw-r--r-- | test/vfd_swmr_common.c | 19 | ||||
-rw-r--r-- | test/vfd_swmr_common.h | 9 | ||||
-rw-r--r-- | test/vfd_swmr_credel.c | 483 | ||||
-rw-r--r-- | test/vfd_swmr_gaussians.c | 753 |
8 files changed, 1 insertions, 1861 deletions
@@ -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 <curses.h> is present and should be used -# HAVE_NCURSESW_H - if <ncursesw.h> should be used -# HAVE_NCURSES_H - if <ncurses.h> should be used -# HAVE_NCURSESW_CURSES_H - if <ncursesw/curses.h> should be used -# HAVE_NCURSES_CURSES_H - if <ncurses/curses.h> 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 <curses.h>. 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 <ncursesw/curses.h> -# #elif defined HAVE_NCURSESW_H -# # include <ncursesw.h> -# #elif defined HAVE_NCURSES_CURSES_H -# # include <ncurses/curses.h> -# #elif defined HAVE_NCURSES_H -# # include <ncurses.h> -# #elif defined HAVE_CURSES_H -# # include <curses.h> -# #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 <mark@kyne.com.au> -# Copyright (c) 2009 Damian Pietras <daper@daper.net> -# Copyright (c) 2012 Reuben Thomas <rrt@sc3d.org> -# Copyright (c) 2011 John Zaitseff <J.Zaitseff@zap.org.au> -# -# 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 <https://www.gnu.org/licenses/>. -# -# 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 <ncursesw/curses.h> - ]], [[ - 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 <ncursesw/curses.h> 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 <ncursesw.h> - ]], [[ - 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 <ncursesw.h> 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 <ncurses.h> - ]], [[ - 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 <ncurses.h> 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 <ncurses/curses.h> - ]], [[ - 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 <ncurses/curses.h> is present]) - ]) - - AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - @%:@include <ncurses.h> - ]], [[ - 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 <ncurses.h> 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 <curses.h> - ]], [[ - 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 <curses.h> 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 <curses.h> - @%:@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 <curses.h> - ]], [[ - 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 <curses.h> - ]], [[ - 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 <stdarg.h> -#include <unistd.h> /* 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 <assert.h> -#include <err.h> -#include <errno.h> -#include <libgen.h> /* basename(3) */ -#include <signal.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> /* struct timespec, nanosleep */ -#include <unistd.h> /* 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 <assert.h> -#include <curses.h> -#include <err.h> -#include <errno.h> -#include <libgen.h> /* basename(3) */ -#include <math.h> /* expf(3) */ -#include <locale.h> /* setlocale(3) */ -#include <signal.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> /* struct timespec, nanosleep(2), time(3), - * clock_gettime(2) - */ -#include <unistd.h> /* getopt, PATH_MAX, ... */ - -#include <sys/param.h> /* 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; -} |