From 3db0a1894f98bb0bc1d178c7aa84ca98c8902f23 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 8 May 2019 15:02:18 +0200 Subject: [PATCH 01/94] Docker raspbian: build and test for raspbian in CI --- .gitlab-ci.yml | 21 +++++++------- packaging/docker/Dockerfile.app-raspbian | 2 +- packaging/docker/Dockerfile.dev-raspbian | 35 ++++++++++++------------ 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6ebe3d33b..ea9878f18 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -38,11 +38,11 @@ prepare:fedora:docker-dev: - shell - linux -#prepare:raspbian:docker-dev: -# extends: prepare:fedora:docker-dev -# variables: -# DOCKER_FILE: packaging/docker/Dockerfile.dev-raspbian -# DOCKER_IMAGE_DEV: villas/node-dev-raspbian +prepare:raspbian:docker-dev: + extends: prepare:fedora:docker-dev + variables: + DOCKER_FILE: packaging/docker/Dockerfile.dev-raspbian + DOCKER_IMAGE_DEV: villas/node-dev-raspbian prepare:ubuntu:docker-dev: extends: prepare:fedora:docker-dev @@ -79,11 +79,12 @@ build:ubuntu:x86_64: LD_PRELOAD: /lib/x86_64-linux-gnu/libSegFault.so DOCKER_IMAGE_DEV: villas/node-dev-ubuntu -#build:raspbian:armv6l: -# extends: build:fedora:x86_64 -# variables: -# LD_PRELOAD: /lib/arm-linux-gnueabihf/libSegFault.so -# DOCKER_IMAGE_DEV: villas/node-dev-raspbian +build:raspbian:armv6l: + extends: build:fedora:x86_64 + variables: + LD_PRELOAD: /lib/arm-linux-gnueabihf/libSegFault.so + DOCKER_IMAGE_DEV: villas/node-dev-raspbian + CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF -DWITH_API=OFF build:docs: stage: build diff --git a/packaging/docker/Dockerfile.app-raspbian b/packaging/docker/Dockerfile.app-raspbian index fa2b8642d..6c593a8a7 100644 --- a/packaging/docker/Dockerfile.app-raspbian +++ b/packaging/docker/Dockerfile.app-raspbian @@ -54,7 +54,7 @@ LABEL \ org.label-schema.vendor = "Institute for Automation of Complex Power Systems, RWTH Aachen University" \ org.label-schema.author.name = "Steffen Vogel" \ org.label-schema.author.email = "stvogel@eonerc.rwth-aachen.de" \ - org.label-schema.description = "A image containing for VILLASnode based on Fedora" \ + org.label-schema.description = "A image containing for VILLASnode based on Raspbian" \ org.label-schema.url = "http://fein-aachen.org/projects/villas-framework/" \ org.label-schema.vcs-url = "https://git.rwth-aachen.de/VILLASframework/VILLASnode" \ org.label-schema.usage = "https://villas.fein-aachen.org/doc/node-installation.html#node-installation-docker" diff --git a/packaging/docker/Dockerfile.dev-raspbian b/packaging/docker/Dockerfile.dev-raspbian index 4e5eba10d..9cc1e39a8 100644 --- a/packaging/docker/Dockerfile.dev-raspbian +++ b/packaging/docker/Dockerfile.dev-raspbian @@ -27,24 +27,15 @@ ARG GIT_BRANCH=unknown ARG VERSION=unknown ARG VARIANT=unknown -RUN echo 'APT::Default-Release "stable";' > /etc/apt/apt.conf.d/99defaultrelease -RUN echo 'deb http://archive.raspbian.org/raspbian buster main contrib non-free rpi firmware' >> /etc/apt/sources.list.d/buster.list - -RUN apt-get install -y -t buster \ - gcc-8 g++-8 cmake - # Toolchain RUN apt-get update && apt-get install -y \ autoconf automake libtool \ - pkg-config make \ - git curl tar bzip2 \ + pkg-config make gcc g++\ + git curl wget tar bzip2 \ protobuf-compiler protobuf-c-compiler -RUN apt-get install -y -t buster \ - gcc-8 g++-8 - # Dependencies -RUN apt-get install -y \ +RUN apt-get install -y\ libssl-dev \ libprotobuf-dev \ libprotobuf-c-dev \ @@ -58,13 +49,23 @@ RUN apt-get install -y \ librabbitmq-dev \ libmosquitto-dev \ libcomedi-dev \ - libibverbs-dev \ librdmacm-dev \ libre-dev \ libusb-1.0-0-dev -ENV CC=gcc-8 -ENV CXX=gcc-8 +ENV CC=gcc +ENV CXX=g++ + +# Build & Install CMake 3.14.1 +RUN cd /tmp && \ + wget https://github.com/Kitware/CMake/releases/download/v3.14.1/cmake-3.14.1.tar.gz && \ + tar -xzf cmake-3.14.1.tar.gz && \ + cd cmake-3.14.1 && ./bootstrap --parallel=$(nproc) -- -DCMAKE_BUILD_TYPE:STRING=Release && \ + make -j$(nproc) && make install && \ + rm -rf /tmp/* + +# Add CMake install dir to PATH +ENV PATH="usr/local/bin:${PATH}" # Build & Install libwebsockets RUN cd /tmp && \ @@ -107,7 +108,7 @@ LABEL \ org.label-schema.vendor="Institute for Automation of Complex Power Systems, RWTH Aachen University" \ org.label-schema.author.name="Steffen Vogel" \ org.label-schema.author.email="stvogel@eonerc.rwth-aachen.de" \ - org.label-schema.description="A image containing all build-time dependencies for VILLASnode based on Ubuntu" \ + org.label-schema.description="A image containing all build-time dependencies for VILLASnode based on Raspbian" \ org.label-schema.url="http://fein-aachen.org/projects/villas-framework/" \ org.label-schema.vcs-url="https://git.rwth-aachen.de/VILLASframework/VILLASnode" \ - org.label-schema.usage="https://villas.fein-aachen.org/doc/node-installation.html#node-installation-docker" \ No newline at end of file + org.label-schema.usage="https://villas.fein-aachen.org/doc/node-installation.html#node-installation-docker" From e8ed440ccf26a745521cc1646c6a9f7f1bad8a11 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 8 May 2019 15:44:19 +0200 Subject: [PATCH 02/94] Fix MSG_TS macro --- include/villas/formats/msg_format.h | 7 +++---- lib/formats/msg.cpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/villas/formats/msg_format.h b/include/villas/formats/msg_format.h index 029cf5210..ed73c9953 100644 --- a/include/villas/formats/msg_format.h +++ b/include/villas/formats/msg_format.h @@ -43,10 +43,9 @@ #define MSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) /** The timestamp of a message in struct timespec format */ -#define MSG_TS(msg) (struct timespec) { \ - .tv_sec = (msg)->ts.sec, \ - .tv_nsec = (msg)->ts.nsec \ -} +#define MSG_TS(msg, i) \ + i.tv_sec = (msg)->ts.sec; \ + i.tv_nsec = (msg)->ts.nsec; /** This message format is used by all clients * diff --git a/lib/formats/msg.cpp b/lib/formats/msg.cpp index 048c38bdb..73a452f72 100644 --- a/lib/formats/msg.cpp +++ b/lib/formats/msg.cpp @@ -84,7 +84,7 @@ int msg_to_sample(struct msg *msg, struct sample *smp, struct vlist *signals) smp->flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; smp->length = MIN(msg->length, smp->capacity); smp->sequence = msg->sequence; - smp->ts.origin = MSG_TS(msg); + MSG_TS(msg, smp->ts.origin); for (unsigned i = 0; i < MIN(smp->length, vlist_length(signals)); i++) { struct signal *sig = (struct signal *) vlist_at(signals, i); From f744d90af9e83546532560e0a363f611ffe656b7 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 8 May 2019 15:56:24 +0200 Subject: [PATCH 03/94] CI: try to build raspbian WITH_API=ON --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ea9878f18..54039741f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -84,7 +84,7 @@ build:raspbian:armv6l: variables: LD_PRELOAD: /lib/arm-linux-gnueabihf/libSegFault.so DOCKER_IMAGE_DEV: villas/node-dev-raspbian - CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF -DWITH_API=OFF + CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF build:docs: stage: build From 0e86d41267d227f7da841de5b6e8312cb1407963 Mon Sep 17 00:00:00 2001 From: Divya Rajashekhar Laxetti Date: Tue, 21 May 2019 17:33:03 +0200 Subject: [PATCH 04/94] Update villas-hook.cpp --- src/villas-hook.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index 74090ab57..2408491ac 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -222,6 +222,12 @@ check: if (optarg == endptr) throw RuntimeError("Failed to read from stdin"); } + + if (!(smp->flags & SAMPLE_HAS_TS_RECEIVED)){ + timespec now = time_now(); + smp->ts.received = now; + smp->flags |= SAMPLE_HAS_TS_RECEIVED; + } logger->debug("Read {} smps from stdin", recv); From 3ae112095dea1ce1158025f0adbf0c41058ce991 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 24 May 2019 10:51:10 +0200 Subject: [PATCH 05/94] fix changes to villas-hook --- src/villas-hook.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index 2408491ac..4ac3455b9 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -222,12 +222,8 @@ check: if (optarg == endptr) throw RuntimeError("Failed to read from stdin"); } - - if (!(smp->flags & SAMPLE_HAS_TS_RECEIVED)){ - timespec now = time_now(); - smp->ts.received = now; - smp->flags |= SAMPLE_HAS_TS_RECEIVED; - } + + timespec now = time_now(); logger->debug("Read {} smps from stdin", recv); @@ -235,6 +231,11 @@ check: if (optarg == endptr) for (int processed = 0; processed < recv; processed++) { struct sample *smp = smps[processed]; + if (!(smp->flags & SAMPLE_HAS_TS_RECEIVED)){ + smp->ts.received = now; + smp->flags |= SAMPLE_HAS_TS_RECEIVED; + } + ret = h->process(smp); switch (ret) { case HOOK_ERROR: From a5f5e02bc301a9de78492a93682aa6f00b6e7e7e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 19 Apr 2019 13:23:00 +0200 Subject: [PATCH 06/94] exceptions: add missing include --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 907e81d81..a5aece6b7 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 907e81d81b466126c09a91e3cd2b93d138cb6b96 +Subproject commit a5aece6b78d5472119d40368ede23a53782faaaf From 492004bf34e62ded36790e1f891be58edcebbd0f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 19 Apr 2019 14:52:52 +0200 Subject: [PATCH 07/94] use new villas::Tool class as common top-level entrypoint --- clients/shmem/villas-shmem.cpp | 179 +++---- src/CMakeLists.txt | 65 +-- .../conf2json.cpp => src/villas-conf2json.cpp | 111 +++-- src/villas-convert.cpp | 126 +++-- src/villas-hook.cpp | 170 ++++--- src/villas-node.cpp | 152 +++--- src/villas-pipe.cpp | 455 +++++++++--------- src/villas-relay.cpp | 430 +++++++++-------- src/villas-relay.hpp | 105 +++- src/villas-signal.cpp | 346 ++++++------- src/villas-test-cmp.cpp | 167 ++++--- src/villas-test-config.cpp | 81 ++-- src/villas-test-rtt.cpp | 137 +++--- .../villas-zmq-keygen.cpp | 61 ++- tools/CMakeLists.txt | 15 - 15 files changed, 1461 insertions(+), 1139 deletions(-) rename tools/conf2json.cpp => src/villas-conf2json.cpp (51%) rename tools/zmq-keygen.cpp => src/villas-zmq-keygen.cpp (64%) diff --git a/clients/shmem/villas-shmem.cpp b/clients/shmem/villas-shmem.cpp index 52dd044c4..ec05694fc 100644 --- a/clients/shmem/villas-shmem.cpp +++ b/clients/shmem/villas-shmem.cpp @@ -23,108 +23,123 @@ * along with this program. If not, see . *********************************************************************************/ -#include #include #include #include -#include -#include #include #include #include #include #include +#include +#include +#include #include -#include +#include -using namespace villas; +namespace villas { +namespace node { +namespace tools { -static std::atomic stop(false); +class Shmem : public Tool { -static void usage() -{ - std::cout << "Usage: villas-test-shmem WNAME VECTORIZE" << std::endl - << " WNAME name of the shared memory object for the output queue" << std::endl - << " RNAME name of the shared memory object for the input queue" << std::endl - << " VECTORIZE maximum number of samples to read/write at a time" << std::endl; +public: + Shmem(int argc, char *argv[]) : + Tool(argc, argv, "shmem"), + stop(false) + { } - print_copyright(); -} +protected: + std::atomic stop; -void quit(int, siginfo_t*, void*) -{ - stop = true; -} + void usage() + { + std::cout << "Usage: villas-test-shmem WNAME VECTORIZE" << std::endl + << " WNAME name of the shared memory object for the output queue" << std::endl + << " RNAME name of the shared memory object for the input queue" << std::endl + << " VECTORIZE maximum number of samples to read/write at a time" << std::endl; -int main(int argc, char* argv[]) -{ - int ret, readcnt, writecnt, avail; - - Logger logger = logging.get("test-shmem"); - - struct shmem_int shm; - struct shmem_conf conf = { - .polling = 0, - .queuelen = DEFAULT_SHMEM_QUEUELEN, - .samplelen = DEFAULT_SHMEM_SAMPLELEN - }; - - if (argc != 4) { - usage(); - return 1; + printCopyright(); } - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to initialize signals"); - - char *wname = argv[1]; - char *rname = argv[2]; - int vectorize = atoi(argv[3]); - - ret = shmem_int_open(wname, rname, &shm, &conf); - if (ret < 0) - throw RuntimeError("Failed to open shared-memory interface"); - - struct sample *insmps[vectorize], *outsmps[vectorize]; - - while (!stop) { - readcnt = shmem_int_read(&shm, insmps, vectorize); - if (readcnt == -1) { - logger->info("Node stopped, exiting"); - break; - } - - avail = shmem_int_alloc(&shm, outsmps, readcnt); - if (avail < readcnt) - logger->warn("Pool underrun: %d / %d\n", avail, readcnt); - - for (int i = 0; i < avail; i++) { - outsmps[i]->sequence = insmps[i]->sequence; - outsmps[i]->ts = insmps[i]->ts; - - int len = MIN(insmps[i]->length, outsmps[i]->capacity); - memcpy(outsmps[i]->data, insmps[i]->data, SAMPLE_DATA_LENGTH(len)); - - outsmps[i]->length = len; - } - - for (int i = 0; i < readcnt; i++) - sample_decref(insmps[i]); - - writecnt = shmem_int_write(&shm, outsmps, avail); - if (writecnt < avail) - logger->warn("Short write"); - - logger->info("Read / Write: {}/{}", readcnt, writecnt); + void handler(int, siginfo_t *, void *) + { + stop = true; } - ret = shmem_int_close(&shm); - if (ret) - throw RuntimeError("Failed to close shared-memory interface"); + int main() + { + int ret, readcnt, writecnt, avail; - logger->info(CLR_GRN("Goodbye!")); + struct shmem_int shm; + struct shmem_conf conf = { + .polling = 0, + .queuelen = DEFAULT_SHMEM_QUEUELEN, + .samplelen = DEFAULT_SHMEM_SAMPLELEN + }; - return 0; + if (argc != 4) { + usage(); + return 1; + } + + std::string wname = argv[1]; + std::string rname = argv[2]; + int vectorize = atoi(argv[3]); + + ret = shmem_int_open(wname.c_str(), rname.c_str(), &shm, &conf); + if (ret < 0) + throw RuntimeError("Failed to open shared-memory interface"); + + struct sample *insmps[vectorize], *outsmps[vectorize]; + + while (!stop) { + readcnt = shmem_int_read(&shm, insmps, vectorize); + if (readcnt == -1) { + logger->info("Node stopped, exiting"); + break; + } + + avail = shmem_int_alloc(&shm, outsmps, readcnt); + if (avail < readcnt) + logger->warn("Pool underrun: %d / %d\n", avail, readcnt); + + for (int i = 0; i < avail; i++) { + outsmps[i]->sequence = insmps[i]->sequence; + outsmps[i]->ts = insmps[i]->ts; + + int len = MIN(insmps[i]->length, outsmps[i]->capacity); + memcpy(outsmps[i]->data, insmps[i]->data, SAMPLE_DATA_LENGTH(len)); + + outsmps[i]->length = len; + } + + for (int i = 0; i < readcnt; i++) + sample_decref(insmps[i]); + + writecnt = shmem_int_write(&shm, outsmps, avail); + if (writecnt < avail) + logger->warn("Short write"); + + logger->info("Read / Write: {}/{}", readcnt, writecnt); + } + + ret = shmem_int_close(&shm); + if (ret) + throw RuntimeError("Failed to close shared-memory interface"); + + return 0; + } +}; + +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::Shmem(argc, argv); + + return t.run(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b9fa7cd82..457facd05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,16 @@ # along with this program. If not, see . ################################################################################### +set(SRCS + villas-node + villas-test-config + villas-test-rtt + villas-test-cmp + villas-convert + villas-pipe + villas-signal +) + add_executable(villas-node villas-node.cpp) target_link_libraries(villas-node PUBLIC villas) @@ -29,24 +39,6 @@ target_link_libraries(villas-test-config PUBLIC villas) add_executable(villas-test-rtt villas-test-rtt.cpp) target_link_libraries(villas-test-rtt PUBLIC villas) -install( - TARGETS villas-node villas-test-rtt - COMPONENT bin - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -if(WITH_WEB) - add_executable(villas-relay villas-relay.cpp) - target_include_directories(villas-relay PRIVATE ${LIBWEBSOCKETS_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/common/include) - target_link_libraries(villas-relay PRIVATE PkgConfig::LIBWEBSOCKETS PkgConfig::UUID villas-common spdlog) - - install( - TARGETS villas-relay - COMPONENT bin - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ) -endif() - add_executable(villas-test-cmp villas-test-cmp.cpp) target_link_libraries(villas-test-cmp PUBLIC villas) @@ -59,20 +51,37 @@ target_link_libraries(villas-pipe PUBLIC villas Threads::Threads) add_executable(villas-signal villas-signal.cpp) target_link_libraries(villas-signal PUBLIC villas) -install( - TARGETS villas-convert villas-pipe villas-signal villas-test-cmp - COMPONENT bin - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) +if(WITH_WEB) + add_executable(villas-relay villas-relay.cpp) + target_include_directories(villas-relay PRIVATE ${LIBWEBSOCKETS_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR}) + target_link_libraries(villas-relay PRIVATE PkgConfig::UUID villas) + + list(APPEND SRCS villas-relay) +endif() + +if(WITH_CONFIG) + add_executable(villas-conf2json villas-conf2json.cpp) + target_link_libraries(villas-conf2json PUBLIC villas) + + list(APPEND SRCS villas-conf2json) +endif() + +if(LIBZMQ_FOUND) + add_executable(villas-zmq-keygen villas-zmq-keygen.cpp) + target_link_libraries(villas-zmq-keygen PUBLIC villas-common PkgConfig::LIBZMQ) + + list(APPEND SRC villas-zmq-keygen) +endif() if(WITH_HOOKS) add_executable(villas-hook villas-hook.cpp) target_link_libraries(villas-hook PUBLIC villas) - install( - TARGETS villas-hook - COMPONENT bin - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ) + list(APPEND SRCS villas-hook) endif() +install( + TARGETS ${SRCS} + COMPONENT bin + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/tools/conf2json.cpp b/src/villas-conf2json.cpp similarity index 51% rename from tools/conf2json.cpp rename to src/villas-conf2json.cpp index 548bc32c8..49e040e75 100644 --- a/tools/conf2json.cpp +++ b/src/villas-conf2json.cpp @@ -28,53 +28,78 @@ #include #include #include -#include +#include -void usage() -{ - std::cout << "Usage: conf2json input.conf > output.json" << std::endl << std::endl; +namespace villas { +namespace node { +namespace tools { - villas::print_copyright(); -} +class Config2Json : public Tool { + +public: + Config2Json(int argc, char *argv[]) : + Tool(argc, argv, "conf2json") + { } + +protected: + + void usage() + { + std::cout << "Usage: conf2json input.conf > output.json" << std::endl << std::endl; + + printCopyright(); + } + + int main() + { + int ret; + config_t cfg; + config_setting_t *cfg_root; + json_t *json; + + if (argc != 2) { + usage(); + exit(EXIT_FAILURE); + } + + FILE *f = fopen(argv[1], "r"); + if(f == nullptr) + return -1; + + const char *confdir = dirname(argv[1]); + + config_init(&cfg); + + config_set_include_dir(&cfg, confdir); + + ret = config_read(&cfg, f); + if (ret != CONFIG_TRUE) + return -2; + + cfg_root = config_root_setting(&cfg); + + json = config_to_json(cfg_root); + if (!json) + return -3; + + ret = json_dumpf(json, stdout, JSON_INDENT(2)); fflush(stdout); + if (ret) + return ret; + + json_decref(json); + config_destroy(&cfg); + + return 0; + } +}; + +} // namespace tools +} // namespace node +} // namespace villas int main(int argc, char *argv[]) { - int ret; - config_t cfg; - config_setting_t *cfg_root; - json_t *json; + auto t = villas::node::tools::Config2Json(argc, argv); - if (argc != 2) { - usage(); - exit(EXIT_FAILURE); - } - - FILE *f = fopen(argv[1], "r"); - if(f == nullptr) - return -1; - - const char *confdir = dirname(argv[1]); - - config_init(&cfg); - - config_set_include_dir(&cfg, confdir); - - ret = config_read(&cfg, f); - if (ret != CONFIG_TRUE) - return -2; - - cfg_root = config_root_setting(&cfg); - - json = config_to_json(cfg_root); - if (!json) - return -3; - - ret = json_dumpf(json, stdout, JSON_INDENT(2)); fflush(stdout); - if (ret) - return ret; - - json_decref(json); - config_destroy(&cfg); - - return 0; + return t.run(); } diff --git a/src/villas-convert.cpp b/src/villas-convert.cpp index a9a7abe33..ee66a18b2 100644 --- a/src/villas-convert.cpp +++ b/src/villas-convert.cpp @@ -26,54 +26,78 @@ #include +#include #include #include #include #include #include #include -#include using namespace villas; -static void usage() -{ - std::cout << "Usage: villas-convert [OPTIONS]" << std::endl - << " OPTIONS are:" << std::endl - << " -i FMT set the input format" << std::endl - << " -o FMT set the output format" << std::endl - << " -t DT the data-type format string" << std::endl - << " -d LVL set debug log level to LVL" << std::endl - << " -h show this usage information" << std::endl - << " -V show the version of the tool" << std::endl << std::endl; +namespace villas { +namespace node { +namespace tools { - print_copyright(); -} +class Convert : public Tool { -int main(int argc, char *argv[]) -{ - Logger logger = logging.get("test-rtt"); - - try { +public: + Convert(int argc, char *argv[]) : + Tool(argc, argv, "convert"), + dtypes("64f") + { int ret; - const char *input_format = "villas.human"; - const char *output_format = "villas.human"; - const char *dtypes = "64f"; + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); + + for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) { + dirs[i].format = "villas.human"; + dirs[i].io.state = STATE_DESTROYED; + } + } + +protected: + std::string dtypes; + + struct { + std::string name; + std::string format; + struct io io; + } dirs[2]; + + void usage() + { + std::cout << "Usage: villas-convert [OPTIONS]" << std::endl + << " OPTIONS are:" << std::endl + << " -i FMT set the input format" << std::endl + << " -o FMT set the output format" << std::endl + << " -t DT the data-type format string" << std::endl + << " -d LVL set debug log level to LVL" << std::endl + << " -h show this usage information" << std::endl + << " -V show the version of the tool" << std::endl << std::endl; + + printCopyright(); + } + + void parse() + { /* Parse optional command line arguments */ int c; while ((c = getopt(argc, argv, "Vhd:i:o:t:")) != -1) { switch (c) { case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'i': - input_format = optarg; + dirs[0].format = optarg; break; case 'o': - output_format = optarg; + dirs[1].format = optarg; break; case 't': @@ -95,36 +119,28 @@ int main(int argc, char *argv[]) usage(); exit(EXIT_FAILURE); } + } - struct format_type *ft; - struct io input; - struct io output; - - input.state = STATE_DESTROYED; - output.state = STATE_DESTROYED; - - struct { - const char *name; - struct io *io; - } dirs[] = { - { input_format, &input }, - { output_format, &output }, - }; + int main() + { + int ret; for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) { - ft = format_type_lookup(dirs[i].name); - if (!ft) - throw RuntimeError("Invalid format: {}", dirs[i].name); + struct format_type *ft; - ret = io_init2(dirs[i].io, ft, dtypes, SAMPLE_HAS_ALL); + ft = format_type_lookup(dirs[i].format.c_str()); + if (!ft) + throw RuntimeError("Invalid format: {}", dirs[i].format); + + ret = io_init2(&dirs[i].io, ft, dtypes.c_str(), SAMPLE_HAS_ALL); if (ret) throw RuntimeError("Failed to initialize IO: {}", dirs[i].name); - ret = io_check(dirs[i].io); + ret = io_check(&dirs[i].io); if (ret) throw RuntimeError("Failed to validate IO configuration"); - ret = io_open(dirs[i].io, nullptr); + ret = io_open(&dirs[i].io, nullptr); if (ret) throw RuntimeError("Failed to open IO"); } @@ -132,32 +148,38 @@ int main(int argc, char *argv[]) struct sample *smp = sample_alloc_mem(DEFAULT_SAMPLE_LENGTH); for (;;) { - ret = io_scan(&input, &smp, 1); + ret = io_scan(&dirs[0].io, &smp, 1); if (ret == 0) continue; if (ret < 0) break; - io_print(&output, &smp, 1); + io_print(&dirs[1].io, &smp, 1); } for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) { - ret = io_close(dirs[i].io); + ret = io_close(&dirs[i].io); if (ret) throw RuntimeError("Failed to close IO"); - ret = io_destroy(dirs[i].io); + ret = io_destroy(&dirs[i].io); if (ret) throw RuntimeError("Failed to destroy IO"); } return 0; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::Convert(argc, argv); + + return t.run(); } /** @} */ diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index 4ac3455b9..0967ba9e8 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -50,66 +50,92 @@ using namespace villas; using namespace villas::node; using namespace villas::plugin; -static std::atomic stop(false); +namespace villas { +namespace node { +namespace tools { -static void quit(int signal, siginfo_t *sinfo, void *ctx) -{ - stop = true; -} +class Hook : public Tool { -static void usage() -{ - std::cout << "Usage: villas-hook [OPTIONS] NAME [[PARAM1] [PARAM2] ...]" << std::endl - << " NAME the name of the hook function" << std::endl - << " PARAM* a string of configuration settings for the hook" << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -f FMT the data format" << std::endl - << " -t DT the data-type format string" << std::endl - << " -d LVL set debug level to LVL" << std::endl - << " -v CNT process CNT smps at once" << std::endl - << " -h show this help" << std::endl - << " -V show the version of the tool" << std::endl << std::endl; +public: + Hook(int argc, char *argv[]) : + Tool(argc, argv, "hook"), + stop(false), + format("villas.human"), + dtypes("64f"), + cnt(1) + { + int ret; -#ifdef WITH_HOOKS - std::cout << "Supported hooks:" << std::endl; - for (Plugin *p : Registry::lookup()) - std::cout << " - " << p->getName() << ": " << p->getDescription() << std::endl; - std::cout << std::endl; -#endif /* WITH_HOOKS */ - - std::cout << "Supported IO formats:" << std::endl; - plugin_dump(PLUGIN_TYPE_FORMAT); - std::cout << std::endl; - - std::cout << "Example:" << std::endl - << " villas-signal random | villas-hook skip_first seconds=10" << std::endl - << std::endl; - - print_copyright(); -} - -int main(int argc, char *argv[]) -{ - int ret, recv, sent, cnt; - const char *format = "villas.human"; - const char *dtypes = "64f"; - - struct format_type *ft; - struct sample **smps; - - Logger logger = logging.get("hook"); - - try { - struct pool p; - struct io io; + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); p.state = STATE_DESTROYED; io.state = STATE_DESTROYED; - /* Default values */ - cnt = 1; + cfg_cli = json_object(); + } - json_t *cfg_cli = json_object(); + ~Hook() + { + json_decref(cfg_cli); + } + +protected: + + std::atomic stop; + + std::string hook; + + std::string format; + std::string dtypes; + + struct pool p; + struct io io; + + int cnt; + + json_t *cfg_cli; + + void handler(int signal, siginfo_t *sinfo, void *ctx) + { + stop = true; + } + + void usage() + { + std::cout << "Usage: villas-hook [OPTIONS] NAME [[PARAM1] [PARAM2] ...]" << std::endl + << " NAME the name of the hook function" << std::endl + << " PARAM* a string of configuration settings for the hook" << std::endl + << " OPTIONS is one or more of the following options:" << std::endl + << " -f FMT the data format" << std::endl + << " -t DT the data-type format string" << std::endl + << " -d LVL set debug level to LVL" << std::endl + << " -v CNT process CNT smps at once" << std::endl + << " -h show this help" << std::endl + << " -V show the version of the tool" << std::endl << std::endl; + +#ifdef WITH_HOOKS + std::cout << "Supported hooks:" << std::endl; + for (Plugin *p : Registry::lookup()) + std::cout << " - " << p->getName() << ": " << p->getDescription() << std::endl; + std::cout << std::endl; +#endif /* WITH_HOOKS */ + + std::cout << "Supported IO formats:" << std::endl; + plugin_dump(PLUGIN_TYPE_FORMAT); + std::cout << std::endl; + + std::cout << "Example:" << std::endl + << " villas-signal random | villas-hook skip_first seconds=10" << std::endl + << std::endl; + + printCopyright(); + } + + void parse() + { + int ret; /* Parse optional command line arguments */ int c; @@ -117,7 +143,7 @@ int main(int argc, char *argv[]) while ((c = getopt(argc, argv, "Vhv:d:f:t:o:")) != -1) { switch (c) { case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'f': @@ -160,19 +186,19 @@ check: if (optarg == endptr) exit(EXIT_FAILURE); } - char *hook = argv[optind]; + hook = argv[optind]; + } - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to intialize signals"); + int main() + { + int ret, recv, sent; + + struct format_type *ft; + struct sample **smps; if (cnt < 1) throw RuntimeError("Vectorize option must be greater than 0"); - ret = memory_init(DEFAULT_NR_HUGEPAGES); - if (ret) - throw RuntimeError("Failed to initialize memory"); - smps = new struct sample*[cnt]; ret = pool_init(&p, 10 * cnt, SAMPLE_LENGTH(DEFAULT_SAMPLE_LENGTH), &memory_hugepage); @@ -180,11 +206,11 @@ check: if (optarg == endptr) throw RuntimeError("Failed to initilize memory pool"); /* Initialize IO */ - ft = format_type_lookup(format); + ft = format_type_lookup(format.c_str()); if (!ft) throw RuntimeError("Unknown IO format '{}'", format); - ret = io_init2(&io, ft, dtypes, SAMPLE_HAS_ALL); + ret = io_init2(&io, ft, dtypes.c_str(), SAMPLE_HAS_ALL); if (ret) throw RuntimeError("Failed to initialize IO"); @@ -280,13 +306,17 @@ stop: sent = io_print(&io, smps, send); if (ret) throw RuntimeError("Failed to destroy memory pool"); - logger->info(CLR_GRN("Goodbye!")); - return 0; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::Hook(argc, argv); + + return t.run(); } diff --git a/src/villas-node.cpp b/src/villas-node.cpp index 4c6af8114..963223145 100644 --- a/src/villas-node.cpp +++ b/src/villas-node.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -42,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -55,74 +55,86 @@ using namespace villas; using namespace villas::node; using namespace villas::plugin; -SuperNode sn; +namespace villas { +namespace node { +namespace tools { -static void quit(int signal, siginfo_t *sinfo, void *ctx) -{ - Logger logger = logging.get("node"); +class Node : public Tool { - switch (signal) { - case SIGALRM: - logger->info("Reached timeout. Terminating..."); - break; +public: + Node(int argc, char *argv[]) : + Tool(argc, argv, "node") + { + int ret; - default: - logger->info("Received {} signal. Terminating...", strsignal(signal)); + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); } - sn.setState(STATE_STOPPING); -} +protected: + SuperNode sn; -static void usage() -{ - std::cout << "Usage: villas-node [OPTIONS] [CONFIG]" << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -h show this usage information" << std::endl - << " -d LVL set logging level" << std::endl - << " -V show the version of the tool" << std::endl << std::endl - << " CONFIG is the path to an optional configuration file" << std::endl - << " if omitted, VILLASnode will start without a configuration" << std::endl - << " and wait for provisioning over the web interface." << std::endl << std::endl + std::string uri; + + void handler(int signal, siginfo_t *sinfo, void *ctx) + { + switch (signal) { + case SIGALRM: + logger->info("Reached timeout. Terminating..."); + break; + + default: + logger->info("Received {} signal. Terminating...", strsignal(signal)); + } + + sn.setState(STATE_STOPPING); + } + + void usage() + { + std::cout << "Usage: villas-node [OPTIONS] [CONFIG]" << std::endl + << " OPTIONS is one or more of the following options:" << std::endl + << " -h show this usage information" << std::endl + << " -d LVL set logging level" << std::endl + << " -V show the version of the tool" << std::endl << std::endl + << " CONFIG is the path to an optional configuration file" << std::endl + << " if omitted, VILLASnode will start without a configuration" << std::endl + << " and wait for provisioning over the web interface." << std::endl << std::endl #ifdef ENABLE_OPAL_ASYNC - << "Usage: villas-node OPAL_ASYNC_SHMEM_NAME OPAL_ASYNC_SHMEM_SIZE OPAL_PRINT_SHMEM_NAME" << std::endl - << " This type of invocation is used by OPAL-RT Asynchronous processes." << std::endl - << " See in the RT-LAB User Guide for more information." << std::endl << std::endl + << "Usage: villas-node OPAL_ASYNC_SHMEM_NAME OPAL_ASYNC_SHMEM_SIZE OPAL_PRINT_SHMEM_NAME" << std::endl + << " This type of invocation is used by OPAL-RT Asynchronous processes." << std::endl + << " See in the RT-LAB User Guide for more information." << std::endl << std::endl #endif /* ENABLE_OPAL_ASYNC */ - << "Supported node-types:" << std::endl; - plugin_dump(PLUGIN_TYPE_NODE); - std::cout << std::endl; + << "Supported node-types:" << std::endl; + plugin_dump(PLUGIN_TYPE_NODE); + std::cout << std::endl; #ifdef WITH_HOOKS - std::cout << "Supported hooks:" << std::endl; - for (Plugin *p : Registry::lookup()) - std::cout << " - " << p->getName() << ": " << p->getDescription() << std::endl; - std::cout << std::endl; + std::cout << "Supported hooks:" << std::endl; + for (Plugin *p : Registry::lookup()) + std::cout << " - " << p->getName() << ": " << p->getDescription() << std::endl; + std::cout << std::endl; #endif /* WITH_HOOKS */ #ifdef WITH_API - std::cout << "Supported API commands:" << std::endl; - for (Plugin *p : Registry::lookup()) - std::cout << " - " << p->getName() << ": " << p->getDescription() << std::endl; - std::cout << std::endl; + std::cout << "Supported API commands:" << std::endl; + for (Plugin *p : Registry::lookup()) + std::cout << " - " << p->getName() << ": " << p->getDescription() << std::endl; + std::cout << std::endl; #endif /* WITH_API */ - std::cout << "Supported IO formats:" << std::endl; - plugin_dump(PLUGIN_TYPE_FORMAT); - std::cout << std::endl; + std::cout << "Supported IO formats:" << std::endl; + plugin_dump(PLUGIN_TYPE_FORMAT); + std::cout << std::endl; - print_copyright(); -} + printCopyright(); + } -int main(int argc, char *argv[]) -{ - int ret; - const char *uri; - - Logger logger = logging.get("node"); - - try { - /* Check arguments */ + void parse() + { + /* Check arguments */ #ifdef ENABLE_OPAL_ASYNC if (argc != 4) { usage(); @@ -139,7 +151,7 @@ int main(int argc, char *argv[]) while ((c = getopt(argc, argv, "hVd:")) != -1) { switch (c) { case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'd': @@ -157,18 +169,15 @@ int main(int argc, char *argv[]) if (argc == optind + 1) uri = argv[optind]; - else if (argc == optind) - uri = nullptr; - else { + else if (argc != optind) { usage(); exit(EXIT_FAILURE); } #endif /* ENABLE_OPAL_ASYNC */ + } - logger->info("This is VILLASnode {} (built on {}, {})", - CLR_BLD(CLR_YEL(PROJECT_BUILD_ID)), - CLR_BLD(CLR_MAG(__DATE__)), CLR_BLD(CLR_MAG(__TIME__))); - + int main() + { #ifdef __linux__ /* Checks system requirements*/ auto required = utils::Version(KERNEL_VERSION_MAJ, KERNEL_VERSION_MIN); @@ -176,11 +185,7 @@ int main(int argc, char *argv[]) throw RuntimeError("Your kernel version is to old: required >= {}.{}", KERNEL_VERSION_MAJ, KERNEL_VERSION_MIN); #endif /* __linux__ */ - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to initialize signal subsystem"); - - if (uri) + if (!uri.empty()) sn.parse(uri); else logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); @@ -191,13 +196,20 @@ int main(int argc, char *argv[]) sn.run(); sn.stop(); - logger->info(CLR_GRN("Goodbye!")); - return 0; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::Node(argc, argv); + + return t.run(); } + +/** @} */ + diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index ec29c7917..8fe37f2c3 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -29,14 +29,14 @@ #include #include #include -#include + +#include #include #include #include #include #include -#include #include #include #include @@ -49,14 +49,25 @@ #include #include #include +#include -using namespace villas; -using namespace villas::node; +namespace villas { +namespace node { +namespace tools { -class Direction { +class PipeDirection { +protected: + struct pool pool; + struct node *node; + struct io *io; + + std::thread thread; + + bool enabled; + int limit; public: - Direction(struct node *n, struct io *i, bool en = true, int lim = -1) : + PipeDirection(struct node *n, struct io *i, bool en = true, int lim = -1) : node(n), io(i), enabled(en), @@ -65,9 +76,6 @@ public: pool.state = STATE_DESTROYED; pool.queue.state = STATE_DESTROYED; - /* Initialize memory */ - - /* Initialize memory */ unsigned vec = LOG2_CEIL(MAX(node->out.vectorize, node->in.vectorize)); unsigned pool_size = node_type(node)->pool_size ? node_type(node)->pool_size : vec; @@ -77,206 +85,236 @@ public: throw RuntimeError("Failed to allocate memory for pool."); } - Direction(const Direction &c) - { - io = c.io; - } - - ~Direction() + ~PipeDirection() { pool_destroy(&pool); } - struct pool pool; - struct node *node; - struct io *io; + virtual void run() + { - pthread_t thread; + } - bool enabled; - int limit; + void startThread() + { + if (enabled) + thread = std::thread(&villas::node::tools::PipeDirection::run, this); + } + + void stopThread() + { + thread.join(); + } }; -struct Directions { - Direction send; - Direction recv; -}; +class PipeSendDirection : public PipeDirection { -static std::atomic stop(false); +public: + PipeSendDirection(struct node *n, struct io *i, bool en = true, int lim = -1) : + PipeDirection(n, i, en, lim) + { } -static void quit(int signal, siginfo_t *sinfo, void *ctx) -{ - Logger logger = logging.get("pipe"); + virtual void run() + { + Logger logger = logging.get("pipe:send"); - switch (signal) { - case SIGALRM: - logger->info("Reached timeout. Terminating..."); - break; + unsigned last_sequenceno = 0, release; + int scanned, sent, allocated, cnt = 0; - default: - logger->info("Received {} signal. Terminating...", strsignal(signal)); - break; - } + struct sample *smps[node->out.vectorize]; - stop = true; -} + while (node->state == STATE_STARTED && !io_eof(io)) { + allocated = sample_alloc_many(&pool, smps, node->out.vectorize); + if (allocated < 0) + throw RuntimeError("Failed to get {} samples out of send pool.", node->out.vectorize); + else if (allocated < (int) node->out.vectorize) + logger->warn("Send pool underrun"); -static void usage() -{ - std::cout << "Usage: villas-pipe [OPTIONS] CONFIG NODE" << std::endl - << " CONFIG path to a configuration file" << std::endl - << " NODE the name of the node to which samples are sent and received from" << std::endl - << " OPTIONS are:" << std::endl - << " -f FMT set the format" << std::endl - << " -t DT the data-type format string" << std::endl - << " -o OPTION=VALUE overwrite options in config file" << std::endl - << " -x swap read / write endpoints" << std::endl - << " -s only read data from stdin and send it to node" << std::endl - << " -r only read data from node and write it to stdout" << std::endl - << " -T NUM terminate after NUM seconds" << std::endl - << " -L NUM terminate after NUM samples sent" << std::endl - << " -l NUM terminate after NUM samples received" << std::endl - << " -h show this usage information" << std::endl - << " -d set logging level" << std::endl - << " -V show the version of the tool" << std::endl << std::endl; + scanned = io_scan(io, smps, allocated); + if (scanned < 0) { + logger->warn("Failed to read samples from stdin"); + continue; + } + else if (scanned == 0) + continue; - print_copyright(); -} + /* Fill in missing sequence numbers */ + for (int i = 0; i < scanned; i++) { + if (smps[i]->flags & SAMPLE_HAS_SEQUENCE) + last_sequenceno = smps[i]->sequence; + else + smps[i]->sequence = last_sequenceno++; + } -static void * send_loop(void *ctx) -{ - Directions *dirs = static_cast(ctx); - Logger logger = logging.get("pipe"); + release = allocated; - unsigned last_sequenceno = 0, release; - int scanned, sent, allocated, cnt = 0; + sent = node_write(node, smps, scanned, &release); - struct node *node = dirs->send.node; - struct sample *smps[node->out.vectorize]; + sample_decref_many(smps, release); - while (node->state == STATE_STARTED && !io_eof(dirs->send.io)) { - allocated = sample_alloc_many(&dirs->send.pool, smps, node->out.vectorize); - if (allocated < 0) - throw RuntimeError("Failed to get {} samples out of send pool.", node->out.vectorize); - else if (allocated < (int) node->out.vectorize) - logger->warn("Send pool underrun"); - - scanned = io_scan(dirs->send.io, smps, allocated); - if (scanned < 0) { - logger->warn("Failed to read samples from stdin"); - continue; - } - else if (scanned == 0) - continue; - - /* Fill in missing sequence numbers */ - for (int i = 0; i < scanned; i++) { - if (smps[i]->flags & SAMPLE_HAS_SEQUENCE) - last_sequenceno = smps[i]->sequence; - else - smps[i]->sequence = last_sequenceno++; - } - - release = allocated; - - sent = node_write(node, smps, scanned, &release); - - sample_decref_many(smps, release); - - cnt += sent; - if (dirs->send.limit > 0 && cnt >= dirs->send.limit) - goto leave; - - pthread_testcancel(); - } - -leave: if (io_eof(dirs->send.io)) { - if (dirs->recv.limit < 0) { - logger->info("Reached end-of-file. Terminating..."); - stop = true; - } - else - logger->info("Reached end-of-file. Wait for receive side..."); - } - else { - logger->info("Reached send limit. Terminating..."); - stop = true; - } - - return nullptr; -} - -static void * recv_loop(void *ctx) -{ - Directions *dirs = static_cast(ctx); - Logger logger = logging.get("pipe"); - - int recv, cnt = 0, allocated = 0; - unsigned release; - struct node *node = dirs->recv.node; - struct sample *smps[node->in.vectorize]; - - while (node->state == STATE_STARTED) { - allocated = sample_alloc_many(&dirs->recv.pool, smps, node->in.vectorize); - if (allocated < 0) - throw RuntimeError("Failed to allocate {} samples from receive pool.", node->in.vectorize); - else if (allocated < (int) node->in.vectorize) - logger->warn("Receive pool underrun: allocated only {} of {} samples", allocated, node->in.vectorize); - - release = allocated; - - recv = node_read(node, smps, allocated, &release); - if (recv < 0) { - if (node->state == STATE_STOPPING) - goto leave2; - else - logger->warn("Failed to receive samples from node {}: reason={}", node_name(node), recv); - } - else { - io_print(dirs->recv.io, smps, recv); - - cnt += recv; - if (dirs->recv.limit > 0 && cnt >= dirs->recv.limit) + cnt += sent; + if (limit > 0 && cnt >= limit) goto leave; } - sample_decref_many(smps, release); - pthread_testcancel(); +leave: if (io_eof(io)) { + if (limit < 0) { + logger->info("Reached end-of-file. Terminating..."); + raise(SIGINT); + } + else + logger->info("Reached end-of-file. Wait for receive side..."); + } + else { + logger->info("Reached send limit. Terminating..."); + raise(SIGINT); + } + } +}; + +class PipeReceiveDirection : public PipeDirection { + +public: + PipeReceiveDirection(struct node *n, struct io *i, bool en = true, int lim = -1) : + PipeDirection(n, i, en, lim) + { } + + virtual void run() + { + Logger logger = logging.get("pipe:recv"); + + int recv, cnt = 0, allocated = 0; + unsigned release; + struct sample *smps[node->in.vectorize]; + + while (node->state == STATE_STARTED) { + allocated = sample_alloc_many(&pool, smps, node->in.vectorize); + if (allocated < 0) + throw RuntimeError("Failed to allocate {} samples from receive pool.", node->in.vectorize); + else if (allocated < (int) node->in.vectorize) + logger->warn("Receive pool underrun: allocated only {} of {} samples", allocated, node->in.vectorize); + + release = allocated; + + recv = node_read(node, smps, allocated, &release); + if (recv < 0) { + if (node->state == STATE_STOPPING) + goto leave2; + else + logger->warn("Failed to receive samples from node {}: reason={}", node_name(node), recv); + } + else { + io_print(io, smps, recv); + + cnt += recv; + if (limit > 0 && cnt >= limit) + goto leave; + } + + sample_decref_many(smps, release); + } + +leave: logger->info("Reached receive limit. Terminating..."); +leave2: raise(SIGINT); + } +}; + +class Pipe : public Tool { + +public: + Pipe(int argc, char *argv[]) : + Tool(argc, argv, "pipe"), + stop(false), + timeout(0), + reverse(false), + format("villas.human"), + dtypes("64f"), + enable_send(true), + enable_recv(true), + limit_send(-1), + limit_recv(-1) + { + int ret; + + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); + + io.state = STATE_DESTROYED; + + cfg_cli = json_object(); } -leave: logger->info("Reached receive limit. Terminating..."); -leave2: stop = true; + ~Pipe() + { + json_decref(cfg_cli); + } - return nullptr; -} +protected: + std::atomic stop; -int main(int argc, char *argv[]) -{ - Logger logger = logging.get("pipe"); + SuperNode sn; /**< The global configuration */ + struct io io; - try { - int ret, timeout = 0; - bool reverse = false; - const char *format = "villas.human"; - const char *dtypes = "64f"; + int timeout; + bool reverse; + std::string format; + std::string dtypes; + std::string uri; + std::string nodestr; - struct node *node; - static struct io io = { .state = STATE_DESTROYED }; + json_t *cfg_cli; - SuperNode sn; /**< The global configuration */ + bool enable_send = true; + bool enable_recv = true; + int limit_send = -1; + int limit_recv = -1; - json_t *cfg_cli = json_object(); + void handler(int signal, siginfo_t *sinfo, void *ctx) + { + switch (signal) { + case SIGALRM: + logger->info("Reached timeout. Terminating..."); + break; - bool enable_send = true, enable_recv = true; - int limit_send = -1, limit_recv = -1; + default: + logger->info("Received {} signal. Terminating...", strsignal(signal)); + break; + } - /* Parse optional command line arguments */ - int c; + stop = true; + } + + void usage() + { + std::cout << "Usage: villas-pipe [OPTIONS] CONFIG NODE" << std::endl + << " CONFIG path to a configuration file" << std::endl + << " NODE the name of the node to which samples are sent and received from" << std::endl + << " OPTIONS are:" << std::endl + << " -f FMT set the format" << std::endl + << " -t DT the data-type format string" << std::endl + << " -o OPTION=VALUE overwrite options in config file" << std::endl + << " -x swap read / write endpoints" << std::endl + << " -s only read data from stdin and send it to node" << std::endl + << " -r only read data from node and write it to stdout" << std::endl + << " -T NUM terminate after NUM seconds" << std::endl + << " -L NUM terminate after NUM samples sent" << std::endl + << " -l NUM terminate after NUM samples received" << std::endl + << " -h show this usage information" << std::endl + << " -d set logging level" << std::endl + << " -V show the version of the tool" << std::endl << std::endl; + + printCopyright(); + } + + void parse() + { + int c, ret; char *endptr; while ((c = getopt(argc, argv, "Vhxrsd:l:L:T:f:t:o:")) != -1) { switch (c) { case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'f': @@ -338,30 +376,29 @@ check: if (optarg == endptr) exit(EXIT_FAILURE); } - logger->info("Logging level: {}", logging.getLevelName()); + uri = argv[optind]; + nodestr = argv[optind+1]; + } - char *uri = argv[optind]; - char *nodestr = argv[optind+1]; + int main() + { + int ret; + + struct node *node; struct format_type *ft; - ret = memory_init(0); - if (ret) - throw RuntimeError("Failed to intialize memory"); + logger->info("Logging level: {}", logging.getLevelName()); - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to initialize signals"); - - if (uri) + if (!uri.empty()) sn.parse(uri); else logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); - ft = format_type_lookup(format); + ft = format_type_lookup(format.c_str()); if (!ft) throw RuntimeError("Invalid format: {}", format); - ret = io_init2(&io, ft, dtypes, SAMPLE_HAS_ALL); + ret = io_init2(&io, ft, dtypes.c_str(), SAMPLE_HAS_ALL); if (ret) throw RuntimeError("Failed to initialize IO"); @@ -406,36 +443,19 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); - /* Start threads */ - Directions dirs = { - .send = Direction(node, &io, enable_send, limit_send), - .recv = Direction(node, &io, enable_recv, limit_recv) - }; + PipeReceiveDirection recv_dir(node, &io, enable_recv, limit_recv); + PipeSendDirection send_dir(node, &io, enable_recv, limit_recv); - if (dirs.recv.enabled) { - dirs.recv.node = node; - pthread_create(&dirs.recv.thread, nullptr, recv_loop, &dirs); - } - - if (dirs.send.enabled) { - dirs.send.node = node; - pthread_create(&dirs.send.thread, nullptr, send_loop, &dirs); - } + recv_dir.startThread(); + send_dir.startThread(); alarm(timeout); while (!stop) sleep(1); - if (dirs.recv.enabled) { - pthread_cancel(dirs.recv.thread); - pthread_join(dirs.recv.thread, nullptr); - } - - if (dirs.send.enabled) { - pthread_cancel(dirs.send.thread); - pthread_join(dirs.send.thread, nullptr); - } + recv_dir.stopThread(); + send_dir.stopThread(); ret = node_stop(node); if (ret) @@ -455,15 +475,20 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to destroy IO"); - logger->info(CLR_GRN("Goodbye!")); - return 0; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } + +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::Pipe(argc, argv); + + return t.run(); } /** @} */ diff --git a/src/villas-relay.cpp b/src/villas-relay.cpp index aeba1137e..31cc660fd 100644 --- a/src/villas-relay.cpp +++ b/src/villas-relay.cpp @@ -31,95 +31,26 @@ #include #include -#include +#include #include +#include +#include #include -#include #include "villas-relay.hpp" -/** The libwebsockets server context. */ -static lws_context *context; -/** The libwebsockets vhost. */ -static lws_vhost *vhost; +namespace villas { +namespace node { +namespace tools { -std::map sessions; - -using Logger = villas::Logger; - -/* Default options */ -struct Options opts = { - .loopback = false, - .port = 8088, - .protocol = "live" -}; - -/** List of libwebsockets protocols. */ -lws_protocols protocols[] = { - { - .name = "http", - .callback = lws_callback_http_dummy, - .per_session_data_size = 0, - .rx_buffer_size = 1024 - }, - { - .name = "http-api", - .callback = http_protocol_cb, - .per_session_data_size = 0, - .rx_buffer_size = 1024 - }, - { - .name = "live", - .callback = protocol_cb, - .per_session_data_size = sizeof(Connection), - .rx_buffer_size = 0 - }, - { nullptr /* terminator */ } -}; - -/** List of libwebsockets extensions. */ -static const lws_extension extensions[] = { - { - "permessage-deflate", - lws_extension_callback_pm_deflate, - "permessage-deflate" - }, - { - "deflate-frame", - lws_extension_callback_pm_deflate, - "deflate_frame" - }, - { nullptr /* terminator */ } -}; - -static const lws_http_mount mount = { - .mount_next = nullptr, /* linked-list "next" */ - .mountpoint = "/api/v1", /* mountpoint URL */ - .origin = nullptr, /* protocol */ - .def = nullptr, - .protocol = "http-api", - .cgienv = nullptr, - .extra_mimetypes = nullptr, - .interpret = nullptr, - .cgi_timeout = 0, - .cache_max_age = 0, - .auth_mask = 0, - .cache_reusable = 0, - .cache_revalidate = 0, - .cache_intermediaries = 0, - .origin_protocol = LWSMPRO_CALLBACK, /* dynamic */ - .mountpoint_len = 7, /* char count */ - .basic_auth_login_file =nullptr, -}; - -Session::Session(Identifier sid) : +RelaySession::RelaySession(Identifier sid) : identifier(sid), connects(0) { Logger logger = villas::logging.get("console"); - logger->info("Session created: {}", identifier); + logger->info("RelaySession created: {}", identifier); sessions[sid] = this; @@ -128,16 +59,16 @@ Session::Session(Identifier sid) : uuid_generate(uuid); } -Session::~Session() +RelaySession::~RelaySession() { Logger logger = villas::logging.get("console"); - logger->info("Session destroyed: {}", identifier); + logger->info("RelaySession destroyed: {}", identifier); sessions.erase(identifier); } -Session * Session::get(lws *wsi) +RelaySession * RelaySession::get(lws *wsi) { Logger logger = villas::logging.get("console"); @@ -157,7 +88,7 @@ Session * Session::get(lws *wsi) auto it = sessions.find(sid); if (it == sessions.end()) { - return new Session(sid); + return new RelaySession(sid); } else { logger->info("Found existing session: {}", sid); @@ -166,7 +97,7 @@ Session * Session::get(lws *wsi) } } -json_t * Session::toJson() const +json_t * RelaySession::toJson() const { json_t *json_connections = json_array(); @@ -188,18 +119,21 @@ json_t * Session::toJson() const ); } -Connection::Connection(lws *w) : +std::map RelaySession::sessions; + +RelayConnection::RelayConnection(lws *w, bool lo) : wsi(w), currentFrame(std::make_shared()), outgoingFrames(), bytes_recv(0), bytes_sent(0), frames_recv(0), - frames_sent(0) + frames_sent(0), + loopback(lo) { Logger logger = villas::logging.get("console"); - session = Session::get(wsi); + session = RelaySession::get(wsi); session->connections[wsi] = this; session->connects++; @@ -210,11 +144,11 @@ Connection::Connection(lws *w) : logger->info("New connection established: session={}, remote={} ({})", session->identifier, name, ip); } -Connection::~Connection() +RelayConnection::~RelayConnection() { Logger logger = villas::logging.get("console"); - logger->info("Connection closed: session={}, remote={} ({})", session->identifier, name, ip); + logger->info("RelayConnection closed: session={}, remote={} ({})", session->identifier, name, ip); session->connections.erase(wsi); @@ -222,7 +156,7 @@ Connection::~Connection() delete session; } -json_t * Connection::toJson() const +json_t * RelayConnection::toJson() const { return json_pack("{ s: s, s: s, s: I, s: I, s: I, s: I, s: I }", "name", name, @@ -235,7 +169,7 @@ json_t * Connection::toJson() const ); } -void Connection::write() +void RelayConnection::write() { int ret; @@ -254,7 +188,7 @@ void Connection::write() lws_callback_on_writable(wsi); } -void Connection::read(void *in, size_t len) +void RelayConnection::read(void *in, size_t len) { Logger logger = villas::logging.get("console"); @@ -264,14 +198,14 @@ void Connection::read(void *in, size_t len) if (lws_is_final_fragment(wsi)) { frames_recv++; - logger->debug("Received frame, relaying to {} connections", session->connections.size() - (opts.loopback ? 0 : 1)); + logger->debug("Received frame, relaying to {} connections", session->connections.size() - (loopback ? 0 : 1)); for (auto p : session->connections) { auto c = p.second; /* We skip the current connection in order * to avoid receiving our own data */ - if (opts.loopback == false && c == this) + if (loopback == false && c == this) continue; c->outgoingFrames.push(currentFrame); @@ -283,7 +217,47 @@ void Connection::read(void *in, size_t len) } } -static void logger_cb(int level, const char *msg) +Relay::Relay(int argc, char *argv[]) : + Tool(argc, argv, "relay"), + stop(false), + loopback(false), + port(8088), + protocol("live") +{ + int ret; + + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); + + /* Initialize logging */ + spdlog::stdout_color_mt("lws"); + lws_set_log_level((1 << LLL_COUNT) - 1, logger_cb); + + protocols = { + { + .name = "http", + .callback = lws_callback_http_dummy, + .per_session_data_size = 0, + .rx_buffer_size = 1024 + }, + { + .name = "http-api", + .callback = http_protocol_cb, + .per_session_data_size = 0, + .rx_buffer_size = 1024 + }, + { + .name = "live", + .callback = protocol_cb, + .per_session_data_size = sizeof(RelayConnection), + .rx_buffer_size = 0 + }, + { nullptr /* terminator */ } + }; +} + +void Relay::logger_cb(int level, const char *msg) { auto log = spdlog::get("lws"); @@ -296,20 +270,34 @@ static void logger_cb(int level, const char *msg) level = LLL_WARN; switch (level) { - case LLL_ERR: log->error("{}", msg); break; - case LLL_WARN: log->warn( "{}", msg); break; - case LLL_INFO: log->info( "{}", msg); break; - default: log->debug("{}", msg); break; + case LLL_ERR: + log->error("{}", msg); + break; + + case LLL_WARN: + log->warn( "{}", msg); + break; + + case LLL_INFO: + log->info( "{}", msg); + break; + + default: + log->debug("{}", msg); + break; } } -int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) +int Relay::http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { int ret; size_t json_len; json_t *json_sessions, *json_body; - Logger logger = villas::logging.get("console"); + lws_context *ctx = lws_get_context(wsi); + void *user_ctx = lws_context_user(ctx); + + Relay *r = reinterpret_cast(user_ctx); unsigned char buf[LWS_PRE + 2048], *start = &buf[LWS_PRE], *end = &buf[sizeof(buf) - LWS_PRE - 1], *p = start; @@ -320,6 +308,7 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi LWS_ILLEGAL_HTTP_CONTENT_LEN, /* no content len */ &p, end)) return 1; + if (lws_finalize_write_http_header(wsi, start, &p, end)) return 1; @@ -331,7 +320,7 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi case LWS_CALLBACK_HTTP_WRITEABLE: json_sessions = json_array(); - for (auto it : sessions) { + for (auto it : RelaySession::sessions) { auto &session = it.second; json_array_append(json_sessions, session->toJson()); @@ -345,9 +334,9 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi "version", PROJECT_VERSION_STR, "hostname", hname, "options", - "loopback", opts.loopback, - "port", opts.port, - "protocol", opts.protocol + "loopback", r->loopback, + "port", r->port, + "protocol", r->protocol.c_str() ); json_len = json_dumpb(json_body, (char *) buf + LWS_PRE, sizeof(buf) - LWS_PRE, JSON_INDENT(4)); @@ -356,7 +345,7 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi if (ret < 0) return ret; - logger->info("Handled API request"); + r->logger->info("Handled API request"); //if (lws_http_transaction_completed(wsi)) return -1; @@ -368,15 +357,19 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi return lws_callback_http_dummy(wsi, reason, user, in, len); } -int protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) +int Relay::protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { - Connection *c = reinterpret_cast(user); + lws_context *ctx = lws_get_context(wsi); + void *user_ctx = lws_context_user(ctx); + + Relay *r = reinterpret_cast(user_ctx); + RelayConnection *c = reinterpret_cast(user); switch (reason) { case LWS_CALLBACK_ESTABLISHED: try { - new (c) Connection(wsi); + new (c) RelayConnection(wsi, r->loopback); } catch (InvalidUrlException &e) { lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (unsigned char *) "Invalid URL", strlen("Invalid URL")); @@ -386,7 +379,7 @@ int protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in break; case LWS_CALLBACK_CLOSED: - c->~Connection(); + c->~RelayConnection(); break; case LWS_CALLBACK_SERVER_WRITEABLE: @@ -404,104 +397,141 @@ int protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in return 0; } -static void usage() +void Relay::usage() { std::cout << "Usage: villas-relay [OPTIONS]" << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -d LVL set debug level" << std::endl - << " -p PORT the port number to listen on" << std::endl - << " -P PROT the websocket protocol" << std::endl - << " -l enable loopback of own data" << std::endl - << " -V show version and exit" << std::endl - << " -h show usage and exit" << std::endl << std::endl; + << " OPTIONS is one or more of the following options:" << std::endl + << " -d LVL set debug level" << std::endl + << " -p PORT the port number to listen on" << std::endl + << " -P PROT the websocket protocol" << std::endl + << " -l enable loopback of own data" << std::endl + << " -V show version and exit" << std::endl + << " -h show usage and exit" << std::endl << std::endl; - villas::print_copyright(); + printCopyright(); } +void Relay::parse() +{ + char c, *endptr; + while ((c = getopt (argc, argv, "hVp:P:ld:")) != -1) { + switch (c) { + case 'd': + spdlog::set_level(spdlog::level::from_str(optarg)); + break; + + case 'p': + port = strtoul(optarg, &endptr, 10); + goto check; + + case 'P': + protocol = optarg; + break; + + case 'l': + loopback = true; + break; + + case 'V': + printVersion(); + exit(EXIT_SUCCESS); + + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + } + + continue; + +check: if (optarg == endptr) { + logger->error("Failed to parse parse option argument '-{} {}'", c, optarg); + exit(EXIT_FAILURE); + } + } + + if (argc - optind < 0) { + usage(); + exit(EXIT_FAILURE); + } +} + +int Relay::main() { + /* Start server */ + lws_context_creation_info ctx_info = { 0 }; + + protocols[2].name = protocol.c_str(); + + ctx_info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + ctx_info.gid = -1; + ctx_info.uid = -1; + ctx_info.protocols = protocols.data(); + ctx_info.extensions = extensions.data(); + ctx_info.port = port; + ctx_info.mounts = &mount; + ctx_info.user = (void *) this; + + context = lws_create_context(&ctx_info); + if (context == nullptr) { + logger->error("WebSocket: failed to initialize server context"); + exit(EXIT_FAILURE); + } + + vhost = lws_create_vhost(context, &ctx_info); + if (vhost == nullptr) { + logger->error("WebSocket: failed to initialize virtual host"); + exit(EXIT_FAILURE); + } + + while (!stop) + lws_service(context, 100); + + return 0; +} + +const std::vector Relay::extensions = { + { + "permessage-deflate", + lws_extension_callback_pm_deflate, + "permessage-deflate" + }, + { + "deflate-frame", + lws_extension_callback_pm_deflate, + "deflate_frame" + }, + { nullptr /* terminator */ } +}; + +const lws_http_mount Relay::mount = { + .mount_next = nullptr, /* linked-list "next" */ + .mountpoint = "/api/v1", /* mountpoint URL */ + .origin = nullptr, /* protocol */ + .def = nullptr, + .protocol = "http-api", + .cgienv = nullptr, + .extra_mimetypes = nullptr, + .interpret = nullptr, + .cgi_timeout = 0, + .cache_max_age = 0, + .auth_mask = 0, + .cache_reusable = 0, + .cache_revalidate = 0, + .cache_intermediaries = 0, + .origin_protocol = LWSMPRO_CALLBACK, /* dynamic */ + .mountpoint_len = 7, /* char count */ + .basic_auth_login_file =nullptr, +}; + +} // namespace tools +} // namespace node +} // namespace villas + int main(int argc, char *argv[]) { - Logger logger = villas::logging.get("console"); + auto t = villas::node::tools::Relay(argc, argv); - try { - /* Initialize logging */ - spdlog::stdout_color_mt("lws"); - lws_set_log_level((1 << LLL_COUNT) - 1, logger_cb); - - /* Start server */ - lws_context_creation_info ctx_info = { 0 }; - - char c, *endptr; - while ((c = getopt (argc, argv, "hVp:P:ld:")) != -1) { - switch (c) { - case 'd': - spdlog::set_level(spdlog::level::from_str(optarg)); - break; - - case 'p': - opts.port = strtoul(optarg, &endptr, 10); - goto check; - - case 'P': - opts.protocol = strdup(optarg); - break; - - case 'l': - opts.loopback = true; - break; - - case 'V': - villas::print_version(); - exit(EXIT_SUCCESS); - - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); - } - - continue; - -check: if (optarg == endptr) { - logger->error("Failed to parse parse option argument '-{} {}'", c, optarg); - exit(EXIT_FAILURE); - } - } - - if (argc - optind < 0) { - usage(); - exit(EXIT_FAILURE); - } - - protocols[2].name = opts.protocol; - - ctx_info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctx_info.gid = -1; - ctx_info.uid = -1; - ctx_info.protocols = protocols; - ctx_info.extensions = extensions; - ctx_info.port = opts.port; - ctx_info.mounts = &mount; - - context = lws_create_context(&ctx_info); - if (context == nullptr) { - logger->error("WebSocket: failed to initialize server context"); - exit(EXIT_FAILURE); - } - - vhost = lws_create_vhost(context, &ctx_info); - if (vhost == nullptr) { - logger->error("WebSocket: failed to initialize virtual host"); - exit(EXIT_FAILURE); - } - - for (;;) - lws_service(context, 100); - - return 0; - } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); - - return -1; - } + return t.run(); } + + diff --git a/src/villas-relay.hpp b/src/villas-relay.hpp index 878a9bc78..0308cefb8 100644 --- a/src/villas-relay.hpp +++ b/src/villas-relay.hpp @@ -33,19 +33,18 @@ #include +namespace villas { +namespace node { +namespace tools { + /* Forward declarations */ lws_callback_function protocol_cb, http_protocol_cb; -class Session; -class Connection; +class Relay; +class RelaySession; +class RelayConnection; class InvalidUrlException { }; -struct Options { - bool loopback; - int port; - const char *protocol; -}; - class Frame : public std::vector { public: Frame() { @@ -62,31 +61,38 @@ public: } }; -class Session { +class RelaySession { + + friend RelayConnection; + friend Relay; + +public: + typedef std::string Identifier; protected: time_t created; uuid_t uuid; -public: - typedef std::string Identifier; - - static Session * get(lws *wsi); - - Session(Identifier sid); - - ~Session(); - - json_t * toJson() const; Identifier identifier; - std::map connections; + std::map connections; int connects; + + static std::map sessions; + +public: + static RelaySession * get(lws *wsi); + + RelaySession(Identifier sid); + + ~RelaySession(); + + json_t * toJson() const; }; -class Connection { +class RelayConnection { protected: lws *wsi; @@ -95,7 +101,7 @@ protected: std::queue> outgoingFrames; - Session *session; + RelaySession *session; char name[128]; char ip[128]; @@ -107,13 +113,62 @@ protected: size_t frames_recv; size_t frames_sent; -public: - Connection(lws *w); + bool loopback; - ~Connection(); +public: + RelayConnection(lws *w, bool lo); + ~RelayConnection(); json_t * toJson() const; void write(); void read(void *in, size_t len); }; + +class Relay : public Tool { + +public: + Relay(int argc, char *argv[]); + +protected: + std::atomic stop; + + /** The libwebsockets server context. */ + lws_context *context; + + /** The libwebsockets vhost. */ + lws_vhost *vhost; + + bool loopback; + int port; + std::string protocol; + + /** List of libwebsockets protocols. */ + std::vector protocols; + + /** List of libwebsockets extensions. */ + static const std::vector extensions; + + static const lws_http_mount mount; + + static void logger_cb(int level, const char *msg); + + static int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); + + static int protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); + + void usage(); + + void parse(); + + int main(); + + void handler(int signal, siginfo_t *sinfo, void *ctx) + { + stop = true; + } +}; + +} // namespace tools +} // namespace node +} // namespace villas diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 8cf72ff84..4079c6a37 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -30,11 +30,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include @@ -45,162 +45,19 @@ using namespace villas; -static std::atomic stop(false); +namespace villas { +namespace node { +namespace tools { -static void usage() -{ - std::cout << "Usage: villas-signal [OPTIONS] SIGNAL" << std::endl - << " SIGNAL is on of the following signal types:" << std::endl - << " mixed" << std::endl - << " random" << std::endl - << " sine" << std::endl - << " triangle" << std::endl - << " square" << std::endl - << " ramp" << std::endl - << " constants" << std::endl - << " counter" << std::endl << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -d LVL set debug level" << std::endl - << " -f FMT set the format" << std::endl - << " -v NUM specifies how many values a message should contain" << std::endl - << " -r HZ how many messages per second" << std::endl - << " -n non real-time mode. do not throttle output." << std::endl - << " -F HZ the frequency of the signal" << std::endl - << " -a FLT the amplitude" << std::endl - << " -D FLT the standard deviation for 'random' signals" << std::endl - << " -o OFF the DC bias" << std::endl - << " -l NUM only send LIMIT messages and stop" << std::endl << std::endl; +class Signal : public Tool { - print_copyright(); -} - -json_t * parse_cli(int argc, char *argv[], char **format) -{ - Logger logger = logging.get("signal"); - - /* Default values */ - double rate = 10; - double frequency = 1; - double amplitude = 1; - double stddev = 0.02; - double offset = 0; - char *type; - int rt = 1; - int values = 1; - int limit = -1; - - /* Parse optional command line arguments */ - int c; - char *endptr; - while ((c = getopt(argc, argv, "v:r:F:f:l:a:D:no:d:hV")) != -1) { - switch (c) { - case 'n': - rt = 0; - break; - - case 'f': - *format = optarg; - break; - - case 'l': - limit = strtoul(optarg, &endptr, 10); - goto check; - - case 'v': - values = strtoul(optarg, &endptr, 10); - goto check; - - case 'r': - rate = strtof(optarg, &endptr); - goto check; - - case 'o': - offset = strtof(optarg, &endptr); - goto check; - - case 'F': - frequency = strtof(optarg, &endptr); - goto check; - - case 'a': - amplitude = strtof(optarg, &endptr); - goto check; - - case 'D': - stddev = strtof(optarg, &endptr); - goto check; - - case 'd': - logging.setLevel(optarg); - break; - - case 'V': - print_version(); - exit(EXIT_SUCCESS); - - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); - } - - continue; - -check: if (optarg == endptr) - logger->warn("Failed to parse parse option argument '-{} {}'", c, optarg); - } - - if (argc != optind + 1) - return nullptr; - - type = argv[optind]; - - return json_pack("{ s: s, s: s, s: f, s: f, s: f, s: f, s: f, s: b, s: i, s: i }", - "type", "signal", - "signal", type, - "rate", rate, - "frequency", frequency, - "amplitude", amplitude, - "stddev", stddev, - "offset", offset, - "realtime", rt, - "values", values, - "limit", limit - ); -} - -static void quit(int signal, siginfo_t *sinfo, void *ctx) -{ - Logger logger = logging.get("signal"); - - switch (signal) { - case SIGALRM: - logger->info("Reached timeout. Terminating..."); - break; - - default: - logger->info("Received {} signal. Terminating...", strsignal(signal)); - } - - stop = true; -} - -int main(int argc, char *argv[]) -{ - Logger logger = logging.get("signal"); - - try { +public: + Signal(int argc, char *argv[]) : + Tool(argc, argv, "signal"), + stop(false), + format("villas.human") + { int ret; - json_t *cfg; - struct node_type *nt; - struct format_type *ft; - - char *format = (char *) "villas.human"; /** @todo hardcoded for now */ - - struct node n; - struct io io; - struct pool q; - struct sample *t; n.state = STATE_DESTROYED; n.in.state = STATE_DESTROYED; @@ -209,13 +66,164 @@ int main(int argc, char *argv[]) q.state = STATE_DESTROYED; q.queue.state = STATE_DESTROYED; - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to intialize signals"); - - ret = memory_init(0); + ret = memory_init(DEFAULT_NR_HUGEPAGES); if (ret) throw RuntimeError("Failed to initialize memory"); + } + +protected: + std::atomic stop; + + struct node n; + struct io io; + struct pool q; + + std::string format; + + void usage() + { + std::cout << "Usage: villas-signal [OPTIONS] SIGNAL" << std::endl + << " SIGNAL is on of the following signal types:" << std::endl + << " mixed" << std::endl + << " random" << std::endl + << " sine" << std::endl + << " triangle" << std::endl + << " square" << std::endl + << " ramp" << std::endl + << " constants" << std::endl + << " counter" << std::endl << std::endl + << " OPTIONS is one or more of the following options:" << std::endl + << " -d LVL set debug level" << std::endl + << " -f FMT set the format" << std::endl + << " -v NUM specifies how many values a message should contain" << std::endl + << " -r HZ how many messages per second" << std::endl + << " -n non real-time mode. do not throttle output." << std::endl + << " -F HZ the frequency of the signal" << std::endl + << " -a FLT the amplitude" << std::endl + << " -D FLT the standard deviation for 'random' signals" << std::endl + << " -o OFF the DC bias" << std::endl + << " -l NUM only send LIMIT messages and stop" << std::endl << std::endl; + + printCopyright(); + } + + json_t * parse_cli(int argc, char *argv[]) + { + /* Default values */ + double rate = 10; + double frequency = 1; + double amplitude = 1; + double stddev = 0.02; + double offset = 0; + std::string type; + int rt = 1; + int values = 1; + int limit = -1; + + /* Parse optional command line arguments */ + int c; + char *endptr; + while ((c = getopt(argc, argv, "v:r:F:f:l:a:D:no:d:hV")) != -1) { + switch (c) { + case 'n': + rt = 0; + break; + + case 'f': + format = optarg; + break; + + case 'l': + limit = strtoul(optarg, &endptr, 10); + goto check; + + case 'v': + values = strtoul(optarg, &endptr, 10); + goto check; + + case 'r': + rate = strtof(optarg, &endptr); + goto check; + + case 'o': + offset = strtof(optarg, &endptr); + goto check; + + case 'F': + frequency = strtof(optarg, &endptr); + goto check; + + case 'a': + amplitude = strtof(optarg, &endptr); + goto check; + + case 'D': + stddev = strtof(optarg, &endptr); + goto check; + + case 'd': + logging.setLevel(optarg); + break; + + case 'V': + printVersion(); + exit(EXIT_SUCCESS); + + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + } + + continue; + +check: if (optarg == endptr) + logger->warn("Failed to parse parse option argument '-{} {}'", c, optarg); + } + + if (argc != optind + 1) + return nullptr; + + type = argv[optind]; + + return json_pack("{ s: s, s: s, s: f, s: f, s: f, s: f, s: f, s: b, s: i, s: i }", + "type", "signal", + "signal", type.c_str(), + "rate", rate, + "frequency", frequency, + "amplitude", amplitude, + "stddev", stddev, + "offset", offset, + "realtime", rt, + "values", values, + "limit", limit + ); + } + + void handler(int signal, siginfo_t *sinfo, void *ctx) + { + Logger logger = logging.get("signal"); + + switch (signal) { + case SIGALRM: + logger->info("Reached timeout. Terminating..."); + break; + + default: + logger->info("Received {} signal. Terminating...", strsignal(signal)); + } + + stop = true; + } + + int main() + { + int ret; + json_t *cfg; + struct node_type *nt; + struct format_type *ft; + + struct sample *t; nt = node_type_lookup("signal"); if (!nt) @@ -225,7 +233,7 @@ int main(int argc, char *argv[]) if (ret) throw RuntimeError("Failed to initialize node"); - cfg = parse_cli(argc, argv, &format); + cfg = parse_cli(argc, argv); if (!cfg) { usage(); exit(EXIT_FAILURE); @@ -237,7 +245,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - ft = format_type_lookup(format); + ft = format_type_lookup(format.c_str()); if (!ft) throw RuntimeError("Invalid output format '{}'", format); @@ -310,15 +318,19 @@ out: sample_decref(t); if (ret) throw RuntimeError("Failed to destroy pool"); - logger->info(CLR_GRN("Goodbye!")); - return 0; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::Signal(argc, argv); + + return t.run(); } /** @} */ diff --git a/src/villas-test-cmp.cpp b/src/villas-test-cmp.cpp index 63c09749d..f06bfc5fe 100644 --- a/src/villas-test-cmp.cpp +++ b/src/villas-test-cmp.cpp @@ -26,38 +26,42 @@ #include +#include #include #include #include #include #include -#include #include #include #include using namespace villas; -class Side { +namespace villas { +namespace node { +namespace tools { + +class TestCmpSide { public: std::string path; + std::string dtypes; struct sample *sample; struct io io; struct format_type *format; - const char *dtypes; - Side(const std::string &pth, struct format_type *fmt, const char *dt, struct pool *p) : + TestCmpSide(const std::string &pth, struct format_type *fmt, const std::string &dt, struct pool *p) : path(pth), - format(fmt), - dtypes(dt) + dtypes(dt), + format(fmt) { int ret; io.state = STATE_DESTROYED; - ret = io_init2(&io, format, dtypes, 0); + ret = io_init2(&io, format, dtypes.c_str(), 0); if (ret) throw RuntimeError("Failed to initialize IO"); @@ -74,7 +78,7 @@ public: throw RuntimeError("Failed to allocate samples"); } - ~Side() noexcept(false) + ~TestCmpSide() noexcept(false) { int ret; @@ -90,46 +94,62 @@ public: } }; -static void usage() -{ - std::cout << "Usage: villas-test-cmp [OPTIONS] FILE1 FILE2 ... FILEn" << std::endl - << " FILE a list of files to compare" << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -d LVL adjust the debug level" << std::endl - << " -e EPS set epsilon for floating point comparisons to EPS" << std::endl - << " -v ignore data values" << std::endl - << " -T ignore timestamp" << std::endl - << " -s ignore sequence no" << std::endl - << " -f FMT file format for all files" << std::endl - << " -t DT the data-type format string" << std::endl - << " -h show this usage information" << std::endl - << " -V show the version of the tool" << std::endl << std::endl - << "Return codes:" << std::endl - << " 0 files are equal" << std::endl - << " 1 file length not equal" << std::endl - << " 2 sequence no not equal" << std::endl - << " 3 timestamp not equal" << std::endl - << " 4 number of values is not equal" << std::endl - << " 5 data is not equal" << std::endl << std::endl; +class TestCmp : public Tool { - print_copyright(); -} +public: + TestCmp(int argc, char *argv[]) : + Tool(argc, argv, "test-cmp"), + epsilon(1e-9), + format("villas.human"), + dtypes("64f"), + flags(SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA | SAMPLE_HAS_TS_ORIGIN) + { + pool.state = STATE_DESTROYED; -int main(int argc, char *argv[]) -{ - Logger logger = logging.get("test-cmp"); + int ret; - try { - int ret, rc = 0; + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); + } - /* Default values */ - double epsilon = 1e-9; - const char *format = "villas.human"; - const char *dtypes = "64f"; - int flags = SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA | SAMPLE_HAS_TS_ORIGIN; +protected: + struct pool pool; - struct pool pool = { .state = STATE_DESTROYED }; + double epsilon; + std::string format; + std::string dtypes; + int flags; + std::vector filenames; + + void usage() + { + std::cout << "Usage: villas-test-cmp [OPTIONS] FILE1 FILE2 ... FILEn" << std::endl + << " FILE a list of files to compare" << std::endl + << " OPTIONS is one or more of the following options:" << std::endl + << " -d LVL adjust the debug level" << std::endl + << " -e EPS set epsilon for floating point comparisons to EPS" << std::endl + << " -v ignore data values" << std::endl + << " -T ignore timestamp" << std::endl + << " -s ignore sequence no" << std::endl + << " -f FMT file format for all files" << std::endl + << " -t DT the data-type format string" << std::endl + << " -h show this usage information" << std::endl + << " -V show the version of the tool" << std::endl << std::endl + << "Return codes:" << std::endl + << " 0 files are equal" << std::endl + << " 1 file length not equal" << std::endl + << " 2 sequence no not equal" << std::endl + << " 3 timestamp not equal" << std::endl + << " 4 number of values is not equal" << std::endl + << " 5 data is not equal" << std::endl << std::endl; + + printCopyright(); + } + + void parse() + { /* Parse Arguments */ int c; char *endptr; @@ -160,7 +180,7 @@ int main(int argc, char *argv[]) break; case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'd': @@ -184,38 +204,41 @@ check: if (optarg == endptr) exit(EXIT_FAILURE); } - int eofs, line, failed; - int n = argc - optind; /* The number of files which we compare */ - Side *s[n]; + /* Open files */ + for (int i = 0; i < argc - optind; i++) + filenames.push_back(argv[optind + i]); + } - ret = memory_init(0); - if (ret) - throw RuntimeError("Failed to initialize memory system"); + int main() + { + int ret, rc = 0, line, failed; + unsigned eofs; - ret = pool_init(&pool, n, SAMPLE_LENGTH(DEFAULT_SAMPLE_LENGTH), &memory_heap); - if (ret) - throw RuntimeError("Failed to initialize pool"); - - struct format_type *fmt = format_type_lookup(format); + struct format_type *fmt = format_type_lookup(format.c_str()); if (!fmt) throw RuntimeError("Invalid IO format: {}", format); /* Open files */ - for (int i = 0; i < n; i++) - s[i] = new Side(argv[optind + i], fmt, dtypes, &pool); + std::vector sides; + for (auto filename : filenames) + sides.push_back(new TestCmpSide(filename, fmt, dtypes, &pool)); + + ret = pool_init(&pool, sides.size(), SAMPLE_LENGTH(DEFAULT_SAMPLE_LENGTH), &memory_heap); + if (ret) + throw RuntimeError("Failed to initialize pool"); line = 0; for (;;) { /* Read next sample from all files */ retry: eofs = 0; - for (int i = 0; i < n; i++) { - ret = io_eof(&s[i]->io); + for (auto side : sides) { + ret = io_eof(&side->io); if (ret) eofs++; } if (eofs) { - if (eofs == n) + if (eofs == sides.size()) ret = 0; else { std::cout << "length unequal" << std::endl; @@ -226,8 +249,8 @@ retry: eofs = 0; } failed = 0; - for (int i = 0; i < n; i++) { - ret = io_scan(&s[i]->io, &s[i]->sample, 1); + for (auto side : sides) { + ret = io_scan(&side->io, &side->sample, 1); if (ret <= 0) failed++; } @@ -235,8 +258,8 @@ retry: eofs = 0; goto retry; /* We compare all files against the first one */ - for (int i = 1; i < n; i++) { - ret = sample_cmp(s[0]->sample, s[i]->sample, epsilon, flags); + for (auto side : sides) { + ret = sample_cmp(sides[0]->sample, side->sample, epsilon, flags); if (ret) { rc = ret; goto out; @@ -246,8 +269,8 @@ retry: eofs = 0; line++; } -out: for (int i = 0; i < n; i++) - delete s[i]; +out: for (auto side : sides) + delete side; ret = pool_destroy(&pool); if (ret) @@ -255,9 +278,15 @@ out: for (int i = 0; i < n; i++) return rc; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::TestCmp(argc, argv); + + return t.run(); } diff --git a/src/villas-test-config.cpp b/src/villas-test-config.cpp index 60ccf489a..86fb50e15 100644 --- a/src/villas-test-config.cpp +++ b/src/villas-test-config.cpp @@ -22,8 +22,8 @@ #include +#include #include -#include #include #include #include @@ -33,27 +33,43 @@ using namespace villas; using namespace villas::node; -static void usage() -{ - std::cout << "Usage: villas-test-config [OPTIONS] CONFIG" << std::endl - << " CONFIG is the path to an optional configuration file" << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -d LVL set debug level" << std::endl - << " -V show version and exit" << std::endl - << " -h show usage and exit" << std::endl << std::endl; +namespace villas { +namespace node { +namespace tools { - print_copyright(); -} +class TestConfig : public Tool { -int main(int argc, char *argv[]) -{ - Logger logger = logging.get("test-config"); +public: + TestConfig(int argc, char *argv[]) : + Tool(argc, argv, "test-config"), + check(false) + { + int ret; - try { - SuperNode sn; + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); + } - bool check = false; +protected: + std::string uri; + bool check; + + void usage() + { + std::cout << "Usage: villas-test-config [OPTIONS] CONFIG" << std::endl + << " CONFIG is the path to an optional configuration file" << std::endl + << " OPTIONS is one or more of the following options:" << std::endl + << " -d LVL set debug level" << std::endl + << " -V show version and exit" << std::endl + << " -h show usage and exit" << std::endl << std::endl; + + printCopyright(); + } + + void parse() + { int c; while ((c = getopt (argc, argv, "hcV")) != -1) { switch (c) { @@ -62,7 +78,7 @@ int main(int argc, char *argv[]) break; case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'h': @@ -77,26 +93,29 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - sn.parse(argv[optind]); + uri = argv[optind]; + } + + int main() + { + SuperNode sn; + + sn.parse(uri); if (check) sn.check(); return 0; } - catch (ParseError &e) { - logger->error("{}", e.what()); +}; - return -1; - } - catch (ConfigError &e) { - logger->error("{}", e.what()); +} // namespace tools +} // namespace node +} // namespace villas - return -1; - } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::TestConfig(argc, argv); - return -1; - } + return t.run(); } diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index be033d822..d848eab74 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -30,10 +30,10 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -47,59 +47,73 @@ using namespace villas; using namespace villas::node; -static std::atomic stop(false); +namespace villas { +namespace node { +namespace tools { -void quit(int signal, siginfo_t *sinfo, void *ctx) -{ - stop = true; -} +class TestRtt : public Tool { -static void usage() -{ - std::cout << "Usage: villas-test-rtt [OPTIONS] CONFIG NODE" << std::endl - << " CONFIG path to a configuration file" << std::endl - << " NODE name of the node which shoud be used" << std::endl - << " OPTIONS is one or more of the following options:" << std::endl - << " -c CNT send CNT messages" << std::endl - << " -f FD use file descriptor FD for result output instead of stdout" << std::endl - << " -b BKTS number of buckets for histogram" << std::endl - << " -w WMUP duration of histogram warmup phase" << std::endl - << " -h show this usage information" << std::endl - << " -V show the version of the tool" << std::endl << std::endl; - - print_copyright(); -} - -int main(int argc, char *argv[]) -{ - Logger logger = logging.get("test-rtt"); - - try { +public: + TestRtt(int argc, char *argv[]) : + Tool(argc, argv, "test-rtt"), + stop(false), + fd(STDOUT_FILENO), + count(-1), + hist_warmup(100), + hist_buckets(20) + { int ret; - struct hist hist; - struct timespec send, recv; + ret = memory_init(DEFAULT_NR_HUGEPAGES); + if (ret) + throw RuntimeError("Failed to initialize memory"); + } - struct sample *smp_send = (struct sample *) new char[SAMPLE_LENGTH(2)]; - struct sample *smp_recv = (struct sample *) new char[SAMPLE_LENGTH(2)]; +protected: + std::atomic stop; - struct node *node; + std::string uri; + std::string nodestr; - SuperNode sn; + SuperNode sn; - /* Test options */ - int count = -1; /**< Amount of messages which should be sent (default: -1 for unlimited) */ + /** File descriptor for Matlab results. + * This allows you to write Matlab results in a seperate log file: + * + * ./test etc/example.conf rtt -f 3 3>> measurement_results.m + */ + int fd; - hist_cnt_t hist_warmup = 100; - int hist_buckets = 20; + /**< Amount of messages which should be sent (default: -1 for unlimited) */ + int count; - /** File descriptor for Matlab results. - * This allows you to write Matlab results in a seperate log file: - * - * ./test etc/example.conf rtt -f 3 3>> measurement_results.m - */ - int fd = STDOUT_FILENO; + hist_cnt_t hist_warmup; + int hist_buckets; + + void handler(int signal, siginfo_t *sinfo, void *ctx) + { + stop = true; + } + + void usage() + { + std::cout << "Usage: villas-test-rtt [OPTIONS] CONFIG NODE" << std::endl + << " CONFIG path to a configuration file" << std::endl + << " NODE name of the node which shoud be used" << std::endl + << " OPTIONS is one or more of the following options:" << std::endl + << " -c CNT send CNT messages" << std::endl + << " -f FD use file descriptor FD for result output instead of stdout" << std::endl + << " -b BKTS number of buckets for histogram" << std::endl + << " -w WMUP duration of histogram warmup phase" << std::endl + << " -h show this usage information" << std::endl + << " -V show the version of the tool" << std::endl << std::endl; + + printCopyright(); + } + + void parse() + { /* Parse Arguments */ int c; char *endptr; @@ -122,7 +136,7 @@ int main(int argc, char *argv[]) goto check; case 'V': - print_version(); + printVersion(); exit(EXIT_SUCCESS); case 'd': @@ -146,14 +160,23 @@ check: if (optarg == endptr) exit(EXIT_FAILURE); } - char *uri = argv[optind]; - char *nodestr = argv[optind + 1]; + uri = argv[optind]; + nodestr = argv[optind + 1]; + } - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to initialize signals subsystem"); + int main() + { + int ret; - if (uri) + struct hist hist; + struct timespec send, recv; + + struct sample *smp_send = (struct sample *) new char[SAMPLE_LENGTH(2)]; + struct sample *smp_recv = (struct sample *) new char[SAMPLE_LENGTH(2)]; + + struct node *node; + + if (!uri.empty()) sn.parse(uri); else logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); @@ -237,9 +260,15 @@ check: if (optarg == endptr) return 0; } - catch (std::runtime_error &e) { - logger->error("{}", e.what()); +}; - return -1; - } +} // namespace tools +} // namespace node +} // namespace villas + +int main(int argc, char *argv[]) +{ + auto t = villas::node::tools::TestRtt(argc, argv); + + return t.run(); } diff --git a/tools/zmq-keygen.cpp b/src/villas-zmq-keygen.cpp similarity index 64% rename from tools/zmq-keygen.cpp rename to src/villas-zmq-keygen.cpp index 2d4ede2ca..2c0bb124e 100644 --- a/tools/zmq-keygen.cpp +++ b/src/villas-zmq-keygen.cpp @@ -31,30 +31,55 @@ #include #include #include +#include #if ZMQ_VERSION_MAJOR < 4 || (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR <= 1) #include #endif +namespace villas { +namespace node { +namespace tools { + +class ZmqKeygen : public Tool { + +public: + ZmqKeygen(int argc, char *argv[]) : + Tool(argc, argv, "zmq-keygen") + { } + +protected: + int main() + { + int ret; + char public_key[41]; + char secret_key[41]; + + ret = zmq_curve_keypair(public_key, secret_key); + if (ret) { + if (zmq_errno() == ENOTSUP) + std::cout << "To use " << argv[0] << ", please install libsodium and then rebuild libzmq." << std::endl; + + exit(EXIT_FAILURE); + } + + std::cout << "# Copy these lines to your 'zeromq' node-configuration" << std::endl; + std::cout << "curve = {" << std::endl; + std::cout << "\tpublic_key = \"" << public_key << "\";" << std::endl; + std::cout << "\tsecret_key = \"" << secret_key << "\";" << std::endl; + std::cout << "}" << std::endl; + + return 0; + } +}; + +} // namespace tools +} // namespace node +} // namespace villas + int main(int argc, char *argv[]) { - int ret; - char public_key[41]; - char secret_key[41]; + auto t = villas::node::tools::ZmqKeygen(argc, argv); - ret = zmq_curve_keypair(public_key, secret_key); - if (ret) { - if (zmq_errno() == ENOTSUP) - std::cout << "To use " << argv[0] << ", please install libsodium and then rebuild libzmq." << std::endl; - - exit(EXIT_FAILURE); - } - - std::cout << "# Copy these lines to your 'zeromq' node-configuration" << std::endl; - std::cout << "curve = {" << std::endl; - std::cout << "\tpublic_key = \"" << public_key << "\";" << std::endl; - std::cout << "\tsecret_key = \"" << secret_key << "\";" << std::endl; - std::cout << "}" << std::endl; - - return 0; + return t.run(); } diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 6f918e026..c23009ac4 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -20,13 +20,6 @@ # along with this program. If not, see . ################################################################################### -if(WITH_CONFIG) - add_executable(conf2json conf2json.cpp) - target_link_libraries(conf2json PUBLIC villas) - - list(APPEND TOOLS conf2json) -endif() - if(CMAKE_SYSTEM_NAME STREQUAL Linux) add_executable(rmshm rmshm.cpp) target_link_libraries(rmshm PUBLIC Threads::Threads rt) @@ -37,14 +30,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux) list(APPEND TOOLS rmsem rmshm) endif() -if(LIBZMQ_FOUND) - add_executable(zmq-keygen zmq-keygen.cpp) - target_include_directories(zmq-keygen PUBLIC ${LIBZMQ_INCLUDE_DIRS}) - target_link_libraries(zmq-keygen PUBLIC PkgConfig::LIBZMQ) - - list(APPEND TOOLS zmq-keygen) -endif() - install( TARGETS ${TOOLS} COMPONENT tools From 05ac6dd61f718c9cc26c5ef8fc5022965d230fb4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 28 May 2019 17:36:23 +0200 Subject: [PATCH 08/94] fix obsolete include filename --- clients/shmem/villas-shmem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clients/shmem/villas-shmem.cpp b/clients/shmem/villas-shmem.cpp index ec05694fc..e4885d9b5 100644 --- a/clients/shmem/villas-shmem.cpp +++ b/clients/shmem/villas-shmem.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include From ebf29432404347dfcc9239cf842d3527b4daae20 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 4 Jun 2019 16:55:38 +0200 Subject: [PATCH 09/94] update VILLAScommon submodule --- common | 2 +- include/villas/stats.h | 2 +- lib/api/actions/restart.cpp | 2 +- lib/api/actions/shutdown.cpp | 2 +- lib/formats/csv.cpp | 2 + lib/formats/protobuf.cpp | 2 + lib/hooks/dp.cpp | 1 + lib/io.cpp | 2 + lib/kernel/if.cpp | 2 + lib/kernel/tc_netem.cpp | 2 + lib/mapping.cpp | 2 + lib/memory/heap.cpp | 2 + lib/memory/hugepage.cpp | 2 + lib/memory/ib.cpp | 2 + lib/memory/managed.cpp | 2 + lib/node.cpp | 2 + lib/node_direction.cpp | 2 + lib/nodes/amqp.cpp | 2 + lib/nodes/comedi.cpp | 2 + lib/nodes/file.cpp | 2 + lib/nodes/iec61850.cpp | 2 + lib/nodes/iec61850_sv.cpp | 2 + lib/nodes/infiniband.cpp | 2 + lib/nodes/influxdb.cpp | 4 +- lib/nodes/loopback.cpp | 4 +- lib/nodes/mqtt.cpp | 2 + lib/nodes/nanomsg.cpp | 2 + lib/nodes/ngsi.cpp | 2 + lib/nodes/rtp.cpp | 1 + lib/nodes/shmem.cpp | 2 + lib/nodes/signal_generator.cpp | 4 +- lib/nodes/socket.cpp | 1 + lib/nodes/stats.cpp | 1 + lib/nodes/test_rtt.cpp | 2 + lib/nodes/uldaq.cpp | 2 + lib/nodes/websocket.cpp | 2 + lib/nodes/zeromq.cpp | 2 + lib/path.cpp | 1 + lib/sample.cpp | 2 + lib/signal.cpp | 2 + lib/socket_addr.cpp | 2 + lib/stats.cpp | 75 ++++++++++++++++++---------------- lib/super_node.cpp | 1 + src/villas-test-rtt.cpp | 20 +++------ 44 files changed, 122 insertions(+), 57 deletions(-) diff --git a/common b/common index a5aece6b7..da710c8ec 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit a5aece6b78d5472119d40368ede23a53782faaaf +Subproject commit da710c8ec3e94b810fe6bb8a98b0ac1debcdcf26 diff --git a/include/villas/stats.h b/include/villas/stats.h index 0668f3243..231398f60 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -88,7 +88,7 @@ struct stats_type_description { struct stats { enum state state; - struct hist histograms[STATS_METRIC_COUNT]; + villas::Hist histograms[STATS_METRIC_COUNT]; }; extern struct stats_metric_description stats_metrics[]; diff --git a/lib/api/actions/restart.cpp b/lib/api/actions/restart.cpp index fb50d452b..97aef50f3 100644 --- a/lib/api/actions/restart.cpp +++ b/lib/api/actions/restart.cpp @@ -99,7 +99,7 @@ public: return ret; /* Properly terminate current instance */ - killme(SIGTERM); + utils::killme(SIGTERM); return 0; } diff --git a/lib/api/actions/shutdown.cpp b/lib/api/actions/shutdown.cpp index 06749c046..9af911dc2 100644 --- a/lib/api/actions/shutdown.cpp +++ b/lib/api/actions/shutdown.cpp @@ -36,7 +36,7 @@ public: virtual int execute(json_t *args, json_t **resp) { - killme(SIGTERM); + utils::killme(SIGTERM); return 0; } diff --git a/lib/formats/csv.cpp b/lib/formats/csv.cpp index e6c98275e..2960e5b1a 100644 --- a/lib/formats/csv.cpp +++ b/lib/formats/csv.cpp @@ -31,6 +31,8 @@ #include #include +using namespace villas::utils; + static size_t csv_sprint_single(struct io *io, char *buf, size_t len, const struct sample *smp) { size_t off = 0; diff --git a/lib/formats/protobuf.cpp b/lib/formats/protobuf.cpp index a4ada3943..f2c58e99e 100644 --- a/lib/formats/protobuf.cpp +++ b/lib/formats/protobuf.cpp @@ -29,6 +29,8 @@ #include #include +using namespace villas::utils; + static enum signal_type protobuf_detect_format(Villas__Node__Value *val) { switch (val->value_case) { diff --git a/lib/hooks/dp.cpp b/lib/hooks/dp.cpp index a7bd08629..d5fc6fd4c 100644 --- a/lib/hooks/dp.cpp +++ b/lib/hooks/dp.cpp @@ -35,6 +35,7 @@ #include using namespace std::complex_literals; +using namespace villas::utils; namespace villas { namespace node { diff --git a/lib/io.cpp b/lib/io.cpp index 3a3783c05..98da97394 100644 --- a/lib/io.cpp +++ b/lib/io.cpp @@ -31,6 +31,8 @@ #include #include +using namespace villas::utils; + static int io_print_lines(struct io *io, struct sample *smps[], unsigned cnt) { int ret; diff --git a/lib/kernel/if.cpp b/lib/kernel/if.cpp index 061823d44..01154721a 100644 --- a/lib/kernel/if.cpp +++ b/lib/kernel/if.cpp @@ -38,6 +38,8 @@ #include +using namespace villas::utils; + int if_init(struct interface *i, struct rtnl_link *link) { i->nl_link = link; diff --git a/lib/kernel/tc_netem.cpp b/lib/kernel/tc_netem.cpp index 94105072b..3df26e03e 100644 --- a/lib/kernel/tc_netem.cpp +++ b/lib/kernel/tc_netem.cpp @@ -34,6 +34,8 @@ #include #include +using namespace villas::utils; + static const double max_percent_value = 0xffffffff; int tc_netem_parse(struct rtnl_qdisc **netem, json_t *cfg) diff --git a/lib/mapping.cpp b/lib/mapping.cpp index c68b91e90..45e77e8fc 100644 --- a/lib/mapping.cpp +++ b/lib/mapping.cpp @@ -29,6 +29,8 @@ #include #include +using namespace villas::utils; + int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *nodes) { char *cpy, *node, *type, *field, *end, *lasts; diff --git a/lib/memory/heap.cpp b/lib/memory/heap.cpp index 8addeca38..e3085c4a5 100644 --- a/lib/memory/heap.cpp +++ b/lib/memory/heap.cpp @@ -25,6 +25,8 @@ #include #include +using namespace villas::utils; + static struct memory_allocation * memory_heap_alloc(struct memory_type *m, size_t len, size_t alignment) { int ret; diff --git a/lib/memory/hugepage.cpp b/lib/memory/hugepage.cpp index 1b0383ed3..64fbfe81e 100644 --- a/lib/memory/hugepage.cpp +++ b/lib/memory/hugepage.cpp @@ -42,6 +42,8 @@ #include #include +using namespace villas::utils; + static size_t pgsz = -1; static size_t hugepgsz = -1; diff --git a/lib/memory/ib.cpp b/lib/memory/ib.cpp index fba1fefef..ddeaf4b09 100644 --- a/lib/memory/ib.cpp +++ b/lib/memory/ib.cpp @@ -27,6 +27,8 @@ #include #include +using namespace villas::utils; + struct ibv_mr * memory_ib_get_mr(void *ptr) { struct memory_allocation *ma; diff --git a/lib/memory/managed.cpp b/lib/memory/managed.cpp index 03d9b8974..c2631929f 100644 --- a/lib/memory/managed.cpp +++ b/lib/memory/managed.cpp @@ -34,6 +34,8 @@ #include #include +using namespace villas::utils; + static struct memory_allocation * memory_managed_alloc(struct memory_type *m, size_t len, size_t alignment) { /* Simple first-fit allocation */ diff --git a/lib/node.cpp b/lib/node.cpp index 950d4a30c..a2b9bbd94 100644 --- a/lib/node.cpp +++ b/lib/node.cpp @@ -43,6 +43,8 @@ #include #endif /* WITH_NETEM */ +using namespace villas::utils; + int node_init(struct node *n, struct node_type *vt) { int ret; diff --git a/lib/node_direction.cpp b/lib/node_direction.cpp index eef6dbcb6..d79ed2841 100644 --- a/lib/node_direction.cpp +++ b/lib/node_direction.cpp @@ -28,6 +28,8 @@ #include #include +using namespace villas::utils; + int node_direction_prepare(struct node_direction *nd, struct node *n) { assert(nd->state == STATE_CHECKED); diff --git a/lib/nodes/amqp.cpp b/lib/nodes/amqp.cpp index 1a485b71d..18f255213 100644 --- a/lib/nodes/amqp.cpp +++ b/lib/nodes/amqp.cpp @@ -30,6 +30,8 @@ #include #include +using namespace villas::utils; + static void amqp_default_ssl_info(struct amqp_ssl_info *s) { s->verify_peer = 1; diff --git a/lib/nodes/comedi.cpp b/lib/nodes/comedi.cpp index 6c2e7c2c1..8ecb0c815 100644 --- a/lib/nodes/comedi.cpp +++ b/lib/nodes/comedi.cpp @@ -31,6 +31,8 @@ #include #include +using namespace villas::utils; + /* Utility functions to dump a comedi_cmd graciously taken from comedilib demo */ static char* comedi_cmd_trigger_src(unsigned int src, char *buf); static void comedi_dump_cmd(comedi_cmd *cmd, int debug_level); diff --git a/lib/nodes/file.cpp b/lib/nodes/file.cpp index 9dccea6e6..403e98d9c 100644 --- a/lib/nodes/file.cpp +++ b/lib/nodes/file.cpp @@ -34,6 +34,8 @@ #include #include +using namespace villas::utils; + static char * file_format_name(const char *format, struct timespec *ts) { struct tm tm; diff --git a/lib/nodes/iec61850.cpp b/lib/nodes/iec61850.cpp index 3ba2115ac..631153d60 100644 --- a/lib/nodes/iec61850.cpp +++ b/lib/nodes/iec61850.cpp @@ -35,6 +35,8 @@ #define CONFIG_SV_DEFAULT_PRIORITY 4 #define CONFIG_SV_DEFAULT_VLAN_ID 0 +using namespace villas::utils; + const struct iec61850_type_descriptor type_descriptors[] = { /* name, iec_type, type, size, supported */ { "boolean", iec61850_type::BOOLEAN, SIGNAL_TYPE_BOOLEAN, 1, false, false }, diff --git a/lib/nodes/iec61850_sv.cpp b/lib/nodes/iec61850_sv.cpp index c8c634039..4b563a0c0 100644 --- a/lib/nodes/iec61850_sv.cpp +++ b/lib/nodes/iec61850_sv.cpp @@ -36,6 +36,8 @@ #define CONFIG_SV_DEFAULT_PRIORITY 4 #define CONFIG_SV_DEFAULT_VLAN_ID 0 +using namespace villas::utils; + static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscriber_ASDU asdu) { struct node *n = (struct node *) ctx; diff --git a/lib/nodes/infiniband.cpp b/lib/nodes/infiniband.cpp index f09f92a0f..a2a49c650 100644 --- a/lib/nodes/infiniband.cpp +++ b/lib/nodes/infiniband.cpp @@ -33,6 +33,8 @@ #include #include +using namespace villas::utils; + static int ib_disconnect(struct node *n) { struct infiniband *ib = (struct infiniband *) n->_vd; diff --git a/lib/nodes/influxdb.cpp b/lib/nodes/influxdb.cpp index 0a1024b83..05aa809a1 100644 --- a/lib/nodes/influxdb.cpp +++ b/lib/nodes/influxdb.cpp @@ -33,6 +33,8 @@ #include #include +using namespace villas::utils; + int influxdb_parse(struct node *n, json_t *json) { struct influxdb *i = (struct influxdb *) n->_vd; @@ -226,4 +228,4 @@ __attribute__((destructor(110))) static void deregister_plugin() { if (plugins.state != STATE_DESTROYED) vlist_remove_all(&plugins, &p); -} \ No newline at end of file +} diff --git a/lib/nodes/loopback.cpp b/lib/nodes/loopback.cpp index 22e438dc8..0c10fc720 100644 --- a/lib/nodes/loopback.cpp +++ b/lib/nodes/loopback.cpp @@ -28,6 +28,8 @@ #include #include +using namespace villas::utils; + int loopback_parse(struct node *n, json_t *cfg) { struct loopback *l = (struct loopback *) n->_vd; @@ -180,4 +182,4 @@ __attribute__((destructor(110))) static void deregister_plugin() { if (plugins.state != STATE_DESTROYED) vlist_remove_all(&plugins, &p); -} \ No newline at end of file +} diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index a1cf96595..f9ca8acd0 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -28,6 +28,8 @@ #include #include +using namespace villas::utils; + static void mqtt_log_cb(struct mosquitto *mosq, void *userdata, int level, const char *str) { switch (level) { diff --git a/lib/nodes/nanomsg.cpp b/lib/nodes/nanomsg.cpp index ec0c3a990..c9a2a805b 100644 --- a/lib/nodes/nanomsg.cpp +++ b/lib/nodes/nanomsg.cpp @@ -29,6 +29,8 @@ #include #include +using namespace villas::utils; + int nanomsg_reverse(struct node *n) { struct nanomsg *m = (struct nanomsg *) n->_vd; diff --git a/lib/nodes/ngsi.cpp b/lib/nodes/ngsi.cpp index f922508d9..ca149017a 100644 --- a/lib/nodes/ngsi.cpp +++ b/lib/nodes/ngsi.cpp @@ -34,6 +34,8 @@ #include #include +using namespace villas::utils; + /* Some global settings */ static char *name = nullptr; diff --git a/lib/nodes/rtp.cpp b/lib/nodes/rtp.cpp index 540fa1e0d..4a2cbc2db 100644 --- a/lib/nodes/rtp.cpp +++ b/lib/nodes/rtp.cpp @@ -54,6 +54,7 @@ extern "C" { static pthread_t re_pthread; using namespace villas::node; +using namespace villas::utils; static struct plugin p; diff --git a/lib/nodes/shmem.cpp b/lib/nodes/shmem.cpp index 7ccbb5358..87dbcda8c 100644 --- a/lib/nodes/shmem.cpp +++ b/lib/nodes/shmem.cpp @@ -36,6 +36,8 @@ #include #include +using namespace villas::utils; + int shmem_parse(struct node *n, json_t *cfg) { struct shmem *shm = (struct shmem *) n->_vd; diff --git a/lib/nodes/signal_generator.cpp b/lib/nodes/signal_generator.cpp index d1ecd9cc5..d9123da8a 100644 --- a/lib/nodes/signal_generator.cpp +++ b/lib/nodes/signal_generator.cpp @@ -28,6 +28,8 @@ #include #include +using namespace villas::utils; + static enum signal_generator::type signal_generator_lookup_type(const char *type) { if (!strcmp(type, "random")) @@ -331,4 +333,4 @@ __attribute__((destructor(110))) static void deregister_plugin() { if (plugins.state != STATE_DESTROYED) vlist_remove_all(&plugins, &p); -} \ No newline at end of file +} diff --git a/lib/nodes/socket.cpp b/lib/nodes/socket.cpp index 0e0569054..cc7388fb1 100644 --- a/lib/nodes/socket.cpp +++ b/lib/nodes/socket.cpp @@ -48,6 +48,7 @@ static struct plugin p; using namespace villas::node; +using namespace villas::utils; int socket_type_start(villas::node::SuperNode *sn) { diff --git a/lib/nodes/stats.cpp b/lib/nodes/stats.cpp index 8bf7db4ba..d1ee7db6d 100644 --- a/lib/nodes/stats.cpp +++ b/lib/nodes/stats.cpp @@ -33,6 +33,7 @@ #define STATS_METRICS 6 using namespace villas::node; +using namespace villas::utils; static struct vlist *nodes; /** The global list of nodes */ diff --git a/lib/nodes/test_rtt.cpp b/lib/nodes/test_rtt.cpp index e815a1382..f7166e6a8 100644 --- a/lib/nodes/test_rtt.cpp +++ b/lib/nodes/test_rtt.cpp @@ -31,6 +31,8 @@ #include #include +using namespace villas::utils; + static struct plugin p; static int test_rtt_case_start(struct test_rtt *t, int id) diff --git a/lib/nodes/uldaq.cpp b/lib/nodes/uldaq.cpp index 0be8ae906..ae36d331d 100644 --- a/lib/nodes/uldaq.cpp +++ b/lib/nodes/uldaq.cpp @@ -30,6 +30,8 @@ #include #include +using namespace villas::utils; + static unsigned num_devs = ULDAQ_MAX_DEV_COUNT; static DaqDeviceDescriptor descriptors[ULDAQ_MAX_DEV_COUNT]; diff --git a/lib/nodes/websocket.cpp b/lib/nodes/websocket.cpp index 966ed2999..025e688ee 100644 --- a/lib/nodes/websocket.cpp +++ b/lib/nodes/websocket.cpp @@ -37,6 +37,8 @@ #include #include +using namespace villas::utils; + #define DEFAULT_WEBSOCKET_BUFFER_SIZE (1 << 12) /* Private static storage */ diff --git a/lib/nodes/zeromq.cpp b/lib/nodes/zeromq.cpp index c54f45469..f640b7a49 100644 --- a/lib/nodes/zeromq.cpp +++ b/lib/nodes/zeromq.cpp @@ -34,6 +34,8 @@ #include #include +using namespace villas::utils; + static void *context; #if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_MAJOR_VERSION >= 4 && ZMQ_MINOR_VERSION >= 2 && ZMQ_MINOR_VERSION >= 3 diff --git a/lib/path.cpp b/lib/path.cpp index 41b28f220..0963945bf 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -45,6 +45,7 @@ #include using namespace villas; +using namespace villas::utils; static void * path_run_single(void *arg) { diff --git a/lib/sample.cpp b/lib/sample.cpp index 7af8b249e..c75ff03c1 100644 --- a/lib/sample.cpp +++ b/lib/sample.cpp @@ -32,6 +32,8 @@ #include #include +using namespace villas::utils; + int sample_init(struct sample *s) { struct pool *p = sample_pool(s); diff --git a/lib/signal.cpp b/lib/signal.cpp index ee9db3a2e..3e41fb902 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -28,6 +28,8 @@ #include #include +using namespace villas::utils; + int signal_init(struct signal *s) { s->enabled = true; diff --git a/lib/socket_addr.cpp b/lib/socket_addr.cpp index 622a67fd1..af293f768 100644 --- a/lib/socket_addr.cpp +++ b/lib/socket_addr.cpp @@ -29,6 +29,8 @@ #include #include +using namespace villas::utils; + char * socket_print_addr(struct sockaddr *saddr) { union sockaddr_union *sa = (union sockaddr_union *) saddr; diff --git a/lib/stats.cpp b/lib/stats.cpp index 7c056a187..3162a9630 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -31,6 +31,9 @@ #include #include +using namespace villas; +using namespace villas::utils; + struct stats_metric_description stats_metrics[] = { { "skipped", STATS_METRIC_SMPS_SKIPPED, "samples", "Skipped samples and the distance between them" }, { "reordered", STATS_METRIC_SMPS_REORDERED, "samples", "Reordered samples and the distance between them" }, @@ -94,7 +97,7 @@ int stats_init(struct stats *s, int buckets, int warmup) assert(s->state == STATE_DESTROYED); for (int i = 0; i < STATS_METRIC_COUNT; i++) - hist_init(&s->histograms[i], buckets, warmup); + new (&s->histograms[i]) Hist(buckets, warmup); s->state = STATE_INITIALIZED; @@ -106,7 +109,7 @@ int stats_destroy(struct stats *s) assert(s->state != STATE_DESTROYED); for (int i = 0; i < STATS_METRIC_COUNT; i++) - hist_destroy(&s->histograms[i]); + s->histograms[i].~Hist(); s->state = STATE_DESTROYED; @@ -117,7 +120,7 @@ void stats_update(struct stats *s, enum stats_metric id, double val) { assert(s->state == STATE_INITIALIZED); - hist_put(&s->histograms[id], val); + s->histograms[id].put(val); } json_t * stats_json(struct stats *s) @@ -128,9 +131,9 @@ json_t * stats_json(struct stats *s) for (int i = 0; i < STATS_METRIC_COUNT; i++) { struct stats_metric_description *d = &stats_metrics[i]; - struct hist *h = &s->histograms[i]; + const Hist &h = s->histograms[i]; - json_object_set_new(obj, d->name, hist_json(h)); + json_object_set_new(obj, d->name, h.toJson()); } return obj; @@ -141,11 +144,11 @@ void stats_reset(struct stats *s) assert(s->state == STATE_INITIALIZED); for (int i = 0; i < STATS_METRIC_COUNT; i++) - hist_reset(&s->histograms[i]); + s->histograms[i].reset(); } static std::vector stats_columns = { - { 10, TableColumn::align::LEFT, "Node", "%s" }, + { 10, TableColumn::align::LEFT, "Node", "%s" }, { 10, TableColumn::align::RIGHT, "Recv", "%ju", "pkts" }, { 10, TableColumn::align::RIGHT, "Sent", "%ju", "pkts" }, { 10, TableColumn::align::RIGHT, "Drop", "%ju", "pkts" }, @@ -179,32 +182,32 @@ void stats_print_periodic(struct stats *s, FILE *f, enum stats_format fmt, struc case STATS_FORMAT_HUMAN: stats_table.row(11, node_name_short(n), - (uintmax_t) hist_total(&s->histograms[STATS_METRIC_OWD]), - (uintmax_t) hist_total(&s->histograms[STATS_METRIC_AGE]), - (uintmax_t) hist_total(&s->histograms[STATS_METRIC_SMPS_REORDERED]), - (uintmax_t) hist_total(&s->histograms[STATS_METRIC_SMPS_SKIPPED]), - (double) hist_last(&s->histograms[STATS_METRIC_OWD]), - (double) hist_mean(&s->histograms[STATS_METRIC_OWD]), - (double) 1.0 / hist_last(&s->histograms[STATS_METRIC_GAP_RECEIVED]), - (double) 1.0 / hist_mean(&s->histograms[STATS_METRIC_GAP_RECEIVED]), - (double) hist_mean(&s->histograms[STATS_METRIC_AGE]), - (double) hist_highest(&s->histograms[STATS_METRIC_AGE]) + (uintmax_t) s->histograms[STATS_METRIC_OWD].getTotal(), + (uintmax_t) s->histograms[STATS_METRIC_AGE].getTotal(), + (uintmax_t) s->histograms[STATS_METRIC_SMPS_REORDERED].getTotal(), + (uintmax_t) s->histograms[STATS_METRIC_SMPS_SKIPPED].getTotal(), + (double) s->histograms[STATS_METRIC_OWD].getLast(), + (double) s->histograms[STATS_METRIC_OWD].getMean(), + (double) 1.0 / s->histograms[STATS_METRIC_GAP_RECEIVED].getLast(), + (double) 1.0 / s->histograms[STATS_METRIC_GAP_RECEIVED].getMean(), + (double) s->histograms[STATS_METRIC_AGE].getMean(), + (double) s->histograms[STATS_METRIC_AGE].getHighest() ); break; case STATS_FORMAT_JSON: { json_t *json_stats = json_pack("{ s: s, s: i, s: i, s: i, s: i, s: f, s: f, s: f, s: f, s: f, s: f }", "node", node_name(n), - "recv", hist_total(&s->histograms[STATS_METRIC_OWD]), - "sent", hist_total(&s->histograms[STATS_METRIC_AGE]), - "dropped", hist_total(&s->histograms[STATS_METRIC_SMPS_REORDERED]), - "skipped", hist_total(&s->histograms[STATS_METRIC_SMPS_SKIPPED]), - "owd_last", 1.0 / hist_last(&s->histograms[STATS_METRIC_OWD]), - "owd_mean", 1.0 / hist_mean(&s->histograms[STATS_METRIC_OWD]), - "rate_last", 1.0 / hist_last(&s->histograms[STATS_METRIC_GAP_SAMPLE]), - "rate_mean", 1.0 / hist_mean(&s->histograms[STATS_METRIC_GAP_SAMPLE]), - "age_mean", hist_mean(&s->histograms[STATS_METRIC_AGE]), - "age_max", hist_highest(&s->histograms[STATS_METRIC_AGE]) + "recv", s->histograms[STATS_METRIC_OWD].getTotal(), + "sent", s->histograms[STATS_METRIC_AGE].getTotal(), + "dropped", s->histograms[STATS_METRIC_SMPS_REORDERED].getTotal(), + "skipped", s->histograms[STATS_METRIC_SMPS_SKIPPED].getTotal(), + "owd_last", 1.0 / s->histograms[STATS_METRIC_OWD].getLast(), + "owd_mean", 1.0 / s->histograms[STATS_METRIC_OWD].getMean(), + "rate_last", 1.0 / s->histograms[STATS_METRIC_GAP_SAMPLE].getLast(), + "rate_mean", 1.0 / s->histograms[STATS_METRIC_GAP_SAMPLE].getMean(), + "age_mean", s->histograms[STATS_METRIC_AGE].getMean(), + "age_max", s->histograms[STATS_METRIC_AGE].getHighest() ); json_dumpf(json_stats, f, 0); break; @@ -224,7 +227,7 @@ void stats_print(struct stats *s, FILE *f, enum stats_format fmt, int verbose) struct stats_metric_description *d = &stats_metrics[i]; info("%s: %s", d->name, d->desc); - hist_print(&s->histograms[i], verbose); + s->histograms[i].print(verbose); } break; @@ -243,36 +246,36 @@ union signal_data stats_get_value(const struct stats *s, enum stats_metric sm, e { assert(s->state == STATE_INITIALIZED); - const struct hist *h = &s->histograms[sm]; + const Hist &h = s->histograms[sm]; union signal_data d; switch (st) { case STATS_TYPE_TOTAL: - d.i = h->total; + d.i = h.getTotal(); break; case STATS_TYPE_LAST: - d.f = h->last; + d.f = h.getLast(); break; case STATS_TYPE_HIGHEST: - d.f = h->highest; + d.f = h.getHighest(); break; case STATS_TYPE_LOWEST: - d.f = h->lowest; + d.f = h.getLowest(); break; case STATS_TYPE_MEAN: - d.f = hist_mean(h); + d.f = h.getMean(); break; case STATS_TYPE_STDDEV: - d.f = hist_stddev(h); + d.f = h.getStddev(); break; case STATS_TYPE_VAR: - d.f = hist_var(h); + d.f = h.getVar(); break; default: diff --git a/lib/super_node.cpp b/lib/super_node.cpp index 857439b1a..918ba2131 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -44,6 +44,7 @@ using namespace villas; using namespace villas::node; +using namespace villas::utils; SuperNode::SuperNode() : state(STATE_INITIALIZED), diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index d848eab74..05f339973 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -168,7 +168,7 @@ check: if (optarg == endptr) { int ret; - struct hist hist; + Hist hist(hist_buckets, hist_warmup); struct timespec send, recv; struct sample *smp_send = (struct sample *) new char[SAMPLE_LENGTH(2)]; @@ -197,10 +197,6 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); - ret = hist_init(&hist, hist_buckets, hist_warmup); - if (ret) - throw RuntimeError("Failed to initialize histogram"); - /* Print header */ fprintf(stdout, "%17s%5s%10s%10s%10s%10s%10s\n", "timestamp", "seq", "rtt", "min", "max", "mean", "stddev"); @@ -222,30 +218,26 @@ check: if (optarg == endptr) if (rtt < 0) logger->warn("Negative RTT: {}", rtt); - hist_put(&hist, rtt); + hist.put(rtt); smp_send->sequence++; fprintf(stdout, "%10lu.%06lu%5" PRIu64 "%10.3f%10.3f%10.3f%10.3f%10.3f\n", recv.tv_sec, recv.tv_nsec / 1000, smp_send->sequence, - 1e3 * rtt, 1e3 * hist.lowest, 1e3 * hist.highest, - 1e3 * hist_mean(&hist), 1e3 * hist_stddev(&hist)); + 1e3 * rtt, 1e3 * hist.getLowest(), 1e3 * hist.getHighest(), + 1e3 * hist.getMean(), 1e3 * hist.getStddev()); } struct stat st; if (!fstat(fd, &st)) { FILE *f = fdopen(fd, "w"); - hist_dump_matlab(&hist, f); + hist.dumpMatlab(f); fclose(f); } else throw RuntimeError("Invalid file descriptor: {}", fd); - hist_print(&hist, 1); - - ret = hist_destroy(&hist); - if (ret) - throw RuntimeError("Failed to destroy histogram"); + hist.print(true); ret = node_stop(node); if (ret) From 8fd096ab179813fcd3ffbcab2a99f3b1c02f75f4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 4 Jun 2019 16:55:50 +0200 Subject: [PATCH 10/94] whitespace cleanups --- lib/formats/csv.cpp | 12 ++++++------ lib/stats.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/formats/csv.cpp b/lib/formats/csv.cpp index 2960e5b1a..481c0edc6 100644 --- a/lib/formats/csv.cpp +++ b/lib/formats/csv.cpp @@ -219,14 +219,14 @@ __attribute__((constructor(110))) static void UNIQUE(__ctor)() { } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) - vlist_remove_all(&plugins, &p1); + if (plugins.state != STATE_DESTROYED) + vlist_remove_all(&plugins, &p1); } static struct plugin p2; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) - vlist_init(&plugins); + if (plugins.state == STATE_DESTROYED) + vlist_init(&plugins); p2.name = "csv"; p2.description = "Comma-separated values"; @@ -243,6 +243,6 @@ __attribute__((constructor(110))) static void UNIQUE(__ctor)() { } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) - vlist_remove_all(&plugins, &p2); + if (plugins.state != STATE_DESTROYED) + vlist_remove_all(&plugins, &p2); } diff --git a/lib/stats.cpp b/lib/stats.cpp index 3162a9630..c930571fb 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -40,7 +40,7 @@ struct stats_metric_description stats_metrics[] = { { "gap_sent", STATS_METRIC_GAP_SAMPLE, "seconds", "Inter-message timestamps (as sent by remote)" }, { "gap_received", STATS_METRIC_GAP_RECEIVED, "seconds", "Inter-message arrival time (as received by this instance)" }, { "owd", STATS_METRIC_OWD, "seconds", "One-way-delay (OWD) of received messages" }, - { "age", STATS_METRIC_AGE, "seconds", "Processing time of packets within the from receive to sent" }, + { "age", STATS_METRIC_AGE, "seconds", "Processing time of packets within the from receive to sent" }, { "rtp.loss_fraction", STATS_METRIC_RTP_LOSS_FRACTION, "percent", "Fraction lost since last RTP SR/RR." }, { "rtp.pkts_lost", STATS_METRIC_RTP_PKTS_LOST, "packets", "Cumulative number of packtes lost" }, { "rtp.jitter", STATS_METRIC_RTP_JITTER, "seconds", "Interarrival jitter" }, From 09a5d810e321151a7189d473e47ac09ec1fb89a9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 5 Jun 2019 18:59:45 +0200 Subject: [PATCH 11/94] exec: add new exec node-type --- CMakeLists.txt | 1 + common | 2 +- etc/examples/nodes/exec.conf | 8 + include/villas/nodes/exec.hpp | 70 ++++++++ lib/nodes/CMakeLists.txt | 4 + lib/nodes/exec.cpp | 211 ++++++++++++++++++++++++ tests/integration/pipe-loopback-exec.sh | 61 +++++++ 7 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 etc/examples/nodes/exec.conf create mode 100644 include/villas/nodes/exec.hpp create mode 100644 lib/nodes/exec.cpp create mode 100755 tests/integration/pipe-loopback-exec.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ce46fb3f..830e0eae1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,7 @@ cmake_dependent_option(WITH_DOC "Build documentation" cmake_dependent_option(WITH_NODE_AMQP "Build with amqp node-type" ON "RABBITMQ_C_FOUND" OFF) cmake_dependent_option(WITH_NODE_COMEDI "Build with comedi node-type" ON "COMEDILIB_FOUND" OFF) cmake_dependent_option(WITH_NODE_FILE "Build with file node-type" ON "" OFF) +cmake_dependent_option(WITH_NODE_EXEC "Build with exec node-type" ON "" OFF) cmake_dependent_option(WITH_NODE_IEC61850 "Build with iec61850 node-types" ON "LIBIEC61850_FOUND" OFF) cmake_dependent_option(WITH_NODE_INFINIBAND "Build with infiniband node-type" ON "IBVERBS_FOUND; RDMACM_FOUND" OFF) cmake_dependent_option(WITH_NODE_INFLUXDB "Build with influxdb node-type" ON "" OFF) diff --git a/common b/common index da710c8ec..7215f711a 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit da710c8ec3e94b810fe6bb8a98b0ac1debcdcf26 +Subproject commit 7215f711a80bf1dde1059925417b0591589be448 diff --git a/etc/examples/nodes/exec.conf b/etc/examples/nodes/exec.conf new file mode 100644 index 000000000..75e3c86ad --- /dev/null +++ b/etc/examples/nodes/exec.conf @@ -0,0 +1,8 @@ +nodes = { + exec_node = { + type = "exec" + format = "villas.human" + flush = true + exec = "tee test" + } +} diff --git a/include/villas/nodes/exec.hpp b/include/villas/nodes/exec.hpp new file mode 100644 index 000000000..adae7f101 --- /dev/null +++ b/include/villas/nodes/exec.hpp @@ -0,0 +1,70 @@ +/** Node-type for exec node-types. + * + * @file + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +/** + * @ingroup node + * @addtogroup exec Execute node-type as a sub-process + * @{ + */ + +#pragma once + +#include +#include + +/* Forward declarations */ +struct node; +struct sample; +struct format_type; + +/** Node-type for signal generation. + * @see node_type + */ +struct exec { + std::unique_ptr proc; + + bool flush; + std::string command; + struct format_type *format; + struct io io; +}; + +/** @see node_type::print */ +char * exec_print(struct node *n); + +/** @see node_type::parse */ +int exec_parse(struct node *n, json_t *cfg); + +/** @see node_type::open */ +int exec_open(struct node *n); + +/** @see node_type::close */ +int exec_close(struct node *n); + +/** @see node_type::read */ +int exec_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release); + +/** @see node_type::write */ +int exec_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release); + +/** @} */ diff --git a/lib/nodes/CMakeLists.txt b/lib/nodes/CMakeLists.txt index 48c0d2d5a..516743f66 100644 --- a/lib/nodes/CMakeLists.txt +++ b/lib/nodes/CMakeLists.txt @@ -55,6 +55,10 @@ if(WITH_NODE_FILE) list(APPEND NODE_SRC file.cpp) endif() +if(WITH_NODE_EXEC) + list(APPEND NODE_SRC exec.cpp) +endif() + # Enable Universal Library for Linux DAQ devices (libuldaq) if(WITH_NODE_ULDAQ) list(APPEND NODE_SRC uldaq.cpp) diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp new file mode 100644 index 000000000..158ae93a9 --- /dev/null +++ b/lib/nodes/exec.cpp @@ -0,0 +1,211 @@ +/** Node-type for subprocess node-types. + * + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +#include + +#include +#include +#include +#include + +using namespace villas::utils; + +int exec_parse(struct node *n, json_t *cfg) +{ + struct exec *e = (struct exec *) n->_vd; + + json_error_t err; + int ret, flush = 0; + + const char *command; + const char *format = "villas.human"; + + ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s?: s, s?: b }", + "exec", &command, + "format", &format, + "flush", &flush + ); + if (ret) + jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + + e->command = command; + e->flush = flush; + + e->format = format_type_lookup(format); + if (!e->format) + error("Invalid format '%s' for node %s", format, node_name(n)); + + if (!(e->format->flags & IO_NEWLINES)) + error("The exec node-type currently supports only line-delimited formats"); + + return 0; +} + +int exec_prepare(struct node *n) +{ + int ret; + struct exec *e = (struct exec *) n->_vd; + + /* Initialize IO */ + ret = io_init(&e->io, e->format, &n->in.signals, SAMPLE_HAS_ALL); + if (ret) + return ret; + + ret = io_check(&e->io); + if (ret) + return ret; + + return 0; +} + +int exec_destroy(struct node *n) +{ + int ret; + struct exec *e = (struct exec *) n->_vd; + + ret = io_destroy(&e->io); + if (ret) + return ret; + + return 0; +} + +int exec_start(struct node *n) +{ + struct exec *e = (struct exec *) n->_vd; + + /* Start subprocess */ + e->proc = std::make_unique(e->command); + debug(2, "Started sub-process with pid=%d", e->proc->getPid()); + + return 0; +} + +int exec_stop(struct node *n) +{ + struct exec *e = (struct exec *) n->_vd; + + /* Stop subprocess */ + debug(2, "Killing sub-process with pid=%d", e->proc->getPid()); + e->proc->kill(SIGINT); + + debug(2, "Waiting for sub-process with pid=%d to terminate", e->proc->getPid()); + e->proc->close(); + + /** @todo: Check exit code of subprocess? */ + return 0; +} + +int exec_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release) +{ + struct exec *e = (struct exec *) n->_vd; + + size_t rbytes; + int avail; + std::string line; + + std::getline(e->proc->cin(), line); + + avail = io_sscan(&e->io, line.c_str(), line.length(), &rbytes, smps, cnt); + if (rbytes - 1 != line.length()) + return -1; + + return avail; +} + +int exec_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release) +{ + struct exec *e = (struct exec *) n->_vd; + + size_t wbytes; + int ret; + char *line = new char[1024]; + + ret = io_sprint(&e->io, line, 1024, &wbytes, smps, cnt); + if (ret < 0) + return ret; + + e->proc->cout() << line; + + if (e->flush) + e->proc->cout().flush(); + + delete line; + + return cnt; +} + +char * exec_print(struct node *n) +{ + struct exec *e = (struct exec *) n->_vd; + char *buf = nullptr; + + strcatf(&buf, "format=%s, exec=%s, flush=%s", + format_type_name(e->format), + e->command.c_str(), + e->flush ? "yes" : "no" + ); + + return buf; +} + +int exec_poll_fds(struct node *n, int fds[]) +{ + struct exec *e = (struct exec *) n->_vd; + + fds[0] = e->proc->getFd(); + + return 1; +} + +static struct plugin p; + +__attribute__((constructor(110))) +static void register_plugin() { + if (plugins.state == STATE_DESTROYED) + vlist_init(&plugins); + + p.name = "exec"; + p.description = "run subprocesses with stdin/stdout communication"; + p.type = PLUGIN_TYPE_NODE; + p.node.instances.state = STATE_DESTROYED; + p.node.vectorize = 0; + p.node.size = sizeof(struct exec); + p.node.parse = exec_parse; + p.node.print = exec_print; + p.node.prepare = exec_prepare; + p.node.destroy = exec_destroy; + p.node.start = exec_start; + p.node.stop = exec_stop; + p.node.read = exec_read; + p.node.write = exec_write; + p.node.poll_fds = exec_poll_fds; + + vlist_init(&p.node.instances); + vlist_push(&plugins, &p); +} + +__attribute__((destructor(110))) +static void deregister_plugin() { + if (plugins.state != STATE_DESTROYED) + vlist_remove_all(&plugins, &p); +} diff --git a/tests/integration/pipe-loopback-exec.sh b/tests/integration/pipe-loopback-exec.sh new file mode 100755 index 000000000..7dba94358 --- /dev/null +++ b/tests/integration/pipe-loopback-exec.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# Integration loopback test for villas-pipe. +# +# @author Steffen Vogel +# @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC +# @license GNU General Public License (version 3) +# +# VILLASnode +# +# 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 +# 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 . +################################################################################## + +SCRIPT=$(realpath $0) +SCRIPTPATH=$(dirname ${SCRIPT}) +source ${SCRIPTPATH}/../../tools/villas-helper.sh + +CONFIG_FILE=$(mktemp) +INPUT_FILE=$(mktemp) +OUTPUT_FILE=$(mktemp) + +NUM_SAMPLES=${NUM_SAMPLES:-100} + +# Generate test data +villas-signal -l ${NUM_SAMPLES} -n random > ${INPUT_FILE} + +FORMAT="villas.human" + +cat > ${CONFIG_FILE} << EOF +{ + "nodes" : { + "node1" : { + "type" : "exec", + "format" : "${FORMAT}", + + "command" : "cat" + } + } +} +EOF + +villas-pipe -l ${NUM_SAMPLES} ${CONFIG_FILE} node1 > ${OUTPUT_FILE} < ${INPUT_FILE} + +# Compare data +villas-test-cmp ${INPUT_FILE} ${OUTPUT_FILE} +RC=$? + +rm ${OUTPUT_FILE} ${INPUT_FILE} ${CONFIG_FILE} + +exit $RC From 6433caac28c92d422280cc7785174bfa00b955c7 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 5 Jun 2019 18:59:57 +0200 Subject: [PATCH 12/94] node: use macro for default sample length --- lib/node_direction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_direction.cpp b/lib/node_direction.cpp index d79ed2841..d5db528fa 100644 --- a/lib/node_direction.cpp +++ b/lib/node_direction.cpp @@ -138,7 +138,7 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg) return ret; } else { - int count = 64; + int count = DEFAULT_SAMPLE_LENGTH; const char *type_str = "float"; if (json_is_object(json_signals)) { From 923ef88fb55b8796d4b8ffd75d6bde7b4c99e087 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 5 Jun 2019 19:00:09 +0200 Subject: [PATCH 13/94] smaller fixes --- src/villas-pipe.cpp | 26 ++++++++++++++++++++++---- src/villas-test-rtt.cpp | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index 8fe37f2c3..c27c67b8c 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -64,12 +64,14 @@ protected: std::thread thread; + bool stop; bool enabled; int limit; public: PipeDirection(struct node *n, struct io *i, bool en = true, int lim = -1) : node(n), io(i), + stop(false), enabled(en), limit(lim) { @@ -97,12 +99,18 @@ public: void startThread() { + stop = false; if (enabled) thread = std::thread(&villas::node::tools::PipeDirection::run, this); } void stopThread() { + stop = true; + + /* We send a signal to the thread in order to interrupt blocking system calls */ + pthread_kill(thread.native_handle(), SIGUSR1); + thread.join(); } }; @@ -123,7 +131,7 @@ public: struct sample *smps[node->out.vectorize]; - while (node->state == STATE_STARTED && !io_eof(io)) { + while (!stop && !io_eof(io)) { allocated = sample_alloc_many(&pool, smps, node->out.vectorize); if (allocated < 0) throw RuntimeError("Failed to get {} samples out of send pool.", node->out.vectorize); @@ -132,6 +140,9 @@ public: scanned = io_scan(io, smps, allocated); if (scanned < 0) { + if (stop) + goto leave2; + logger->warn("Failed to read samples from stdin"); continue; } @@ -157,6 +168,8 @@ public: goto leave; } +leave2: return; + leave: if (io_eof(io)) { if (limit < 0) { logger->info("Reached end-of-file. Terminating..."); @@ -187,7 +200,7 @@ public: unsigned release; struct sample *smps[node->in.vectorize]; - while (node->state == STATE_STARTED) { + while (!stop) { allocated = sample_alloc_many(&pool, smps, node->in.vectorize); if (allocated < 0) throw RuntimeError("Failed to allocate {} samples from receive pool.", node->in.vectorize); @@ -198,7 +211,7 @@ public: recv = node_read(node, smps, allocated, &release); if (recv < 0) { - if (node->state == STATE_STOPPING) + if (node->state == STATE_STOPPING || stop) goto leave2; else logger->warn("Failed to receive samples from node {}: reason={}", node_name(node), recv); @@ -214,6 +227,8 @@ public: sample_decref_many(smps, release); } + return; + leave: logger->info("Reached receive limit. Terminating..."); leave2: raise(SIGINT); } @@ -273,10 +288,13 @@ protected: void handler(int signal, siginfo_t *sinfo, void *ctx) { switch (signal) { - case SIGALRM: + case SIGALRM: logger->info("Reached timeout. Terminating..."); break; + case SIGUSR1: + break; /* ignore silently */ + default: logger->info("Received {} signal. Terminating...", strsignal(signal)); break; diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index 05f339973..3d9d6021d 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -88,7 +88,7 @@ protected: int count; - hist_cnt_t hist_warmup; + Hist::cnt_t hist_warmup; int hist_buckets; void handler(int signal, siginfo_t *sinfo, void *ctx) From c863cac8042de15a8ccd8bd6daaab3ca87ff48de Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 11 Jun 2019 16:20:35 +0000 Subject: [PATCH 14/94] cast: throw exception for invalid signals --- lib/hooks/cast.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/hooks/cast.cpp b/lib/hooks/cast.cpp index 7919ee4c3..2cd5c1589 100644 --- a/lib/hooks/cast.cpp +++ b/lib/hooks/cast.cpp @@ -81,6 +81,8 @@ public: enum signal_type type; orig_sig = (struct signal *) vlist_at_safe(&signals, signal_index); + if (!orig_sig) + throw RuntimeError("Failed to find signal: {}", signal_name); type = new_type != SIGNAL_TYPE_INVALID ? new_type : orig_sig->type; name = new_name ? new_name : orig_sig->name; From 4a8d2bfc2b5370e57a9587b9e16e2f4d17e0799c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 11 Jun 2019 18:32:58 +0200 Subject: [PATCH 15/94] hooks: use exceptions for error handling --- include/villas/hook_list.hpp | 10 +++---- lib/hook_list.cpp | 58 ++++++++---------------------------- lib/node_direction.cpp | 21 +++---------- lib/path.cpp | 12 ++------ 4 files changed, 25 insertions(+), 76 deletions(-) diff --git a/include/villas/hook_list.hpp b/include/villas/hook_list.hpp index 522bc2dc8..7706c46dc 100644 --- a/include/villas/hook_list.hpp +++ b/include/villas/hook_list.hpp @@ -57,9 +57,9 @@ int hook_list_destroy(struct vlist *hs); * hooks = [ "print" ] * } */ -int hook_list_parse(struct vlist *hs, json_t *cfg, int mask, struct path *p, struct node *n); +void hook_list_parse(struct vlist *hs, json_t *cfg, int mask, struct path *p, struct node *n); -int hook_list_prepare(struct vlist *hs, struct vlist *sigs, int mask, struct path *p, struct node *n); +void hook_list_prepare(struct vlist *hs, struct vlist *sigs, int mask, struct path *p, struct node *n); int hook_list_prepare_signals(struct vlist *hs, struct vlist *signals); @@ -67,10 +67,10 @@ int hook_list_add(struct vlist *hs, int mask, struct path *p, struct node *n); int hook_list_process(struct vlist *hs, struct sample *smps[], unsigned cnt); -int hook_list_periodic(struct vlist *hs); +void hook_list_periodic(struct vlist *hs); -int hook_list_start(struct vlist *hs); +void hook_list_start(struct vlist *hs); -int hook_list_stop(struct vlist *hs); +void hook_list_stop(struct vlist *hs); struct vlist * hook_list_get_signals(struct vlist *hs); diff --git a/lib/hook_list.cpp b/lib/hook_list.cpp index 1124997d7..18116b567 100644 --- a/lib/hook_list.cpp +++ b/lib/hook_list.cpp @@ -58,11 +58,10 @@ int hook_list_destroy(vlist *hs) return 0; } -int hook_list_parse(vlist *hs, json_t *cfg, int mask, struct path *o, struct node *n) +void hook_list_parse(vlist *hs, json_t *cfg, int mask, struct path *o, struct node *n) { if (!json_is_array(cfg)) - //throw ConfigError(cfg, "node-config-hook", "Hooks must be configured as a list of hook objects"); - return -1; + throw ConfigError(cfg, "node-config-hook", "Hooks must be configured as a list of hook objects"); size_t i; json_t *json_hook; @@ -83,19 +82,12 @@ int hook_list_parse(vlist *hs, json_t *cfg, int mask, struct path *o, struct nod if (!(hf->getFlags() & mask)) throw ConfigError(json_hook, "node-config-hook", "Hook '{}' not allowed here", type); - try { - h = hf->make(o, n); - h->parse(json_hook); - h->check(); - } - catch (...) { - return -1; - } + h = hf->make(o, n); + h->parse(json_hook); + h->check(); vlist_push(hs, h); } - - return 0; } static int hook_cmp_priority(const Hook *a, const Hook *b) @@ -108,7 +100,7 @@ static int hook_is_enabled(const Hook *h) return h->isEnabled() ? 0 : -1; } -int hook_list_prepare(vlist *hs, vlist *sigs, int m, struct path *p, struct node *n) +void hook_list_prepare(vlist *hs, vlist *sigs, int m, struct path *p, struct node *n) { assert(hs->state == STATE_INITIALIZED); @@ -134,16 +126,10 @@ skip_add: for (size_t i = 0; i < vlist_length(hs); i++) { Hook *h = (Hook *) vlist_at(hs, i); - try { - h->prepare(sigs); - } catch (...) { - return -1; - } + h->prepare(sigs); sigs = h->getSignals(); } - - return 0; } int hook_list_process(vlist *hs, sample *smps[], unsigned cnt) @@ -182,49 +168,31 @@ skip: {} stop: return processed; } -int hook_list_periodic(vlist *hs) +void hook_list_periodic(vlist *hs) { for (size_t j = 0; j < vlist_length(hs); j++) { Hook *h = (Hook *) vlist_at(hs, j); - try { - h->periodic(); - } catch (...) { - return -1; - } + h->periodic(); } - - return 0; } -int hook_list_start(vlist *hs) +void hook_list_start(vlist *hs) { for (size_t i = 0; i < vlist_length(hs); i++) { Hook *h = (Hook *) vlist_at(hs, i); - try { - h->start(); - } catch (...) { - return -1; - } + h->start(); } - - return 0; } -int hook_list_stop(vlist *hs) +void hook_list_stop(vlist *hs) { for (size_t i = 0; i < vlist_length(hs); i++) { Hook *h = (Hook *) vlist_at(hs, i); - try { - h->stop(); - } catch (...) { - return -1; - } + h->stop(); } - - return 0; } vlist * hook_list_get_signals(vlist *hs) diff --git a/lib/node_direction.cpp b/lib/node_direction.cpp index d5db528fa..130d12f8c 100644 --- a/lib/node_direction.cpp +++ b/lib/node_direction.cpp @@ -35,13 +35,10 @@ int node_direction_prepare(struct node_direction *nd, struct node *n) assert(nd->state == STATE_CHECKED); #ifdef WITH_HOOKS - int ret; int t = nd->direction == NODE_DIR_OUT ? HOOK_NODE_WRITE : HOOK_NODE_READ; int m = nd->builtin ? t | HOOK_BUILTIN : 0; - ret = hook_list_prepare(&nd->hooks, &nd->signals, m, nullptr, n); - if (ret) - return ret; + hook_list_prepare(&nd->hooks, &nd->signals, m, nullptr, n); #endif /* WITH_HOOKS */ nd->state = STATE_PREPARED; @@ -161,9 +158,7 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg) if (json_hooks) { int m = nd->direction == NODE_DIR_OUT ? HOOK_NODE_WRITE : HOOK_NODE_READ; - ret = hook_list_parse(&nd->hooks, json_hooks, m, nullptr, n); - if (ret < 0) - return ret; + hook_list_parse(&nd->hooks, json_hooks, m, nullptr, n); } #endif /* WITH_HOOKS */ @@ -193,11 +188,7 @@ int node_direction_start(struct node_direction *nd, struct node *n) assert(nd->state == STATE_PREPARED); #ifdef WITH_HOOKS - int ret; - - ret = hook_list_start(&nd->hooks); - if (ret) - return ret; + hook_list_start(&nd->hooks); #endif /* WITH_HOOKS */ nd->state = STATE_STARTED; @@ -210,11 +201,7 @@ int node_direction_stop(struct node_direction *nd, struct node *n) assert(nd->state == STATE_STARTED); #ifdef WITH_HOOKS - int ret; - - ret = hook_list_stop(&nd->hooks); - if (ret) - return ret; + hook_list_stop(&nd->hooks); #endif /* WITH_HOOKS */ nd->state = STATE_STOPPED; diff --git a/lib/path.cpp b/lib/path.cpp index 0963945bf..f2904773d 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -284,9 +284,7 @@ int path_prepare(struct path *p) int m = p->builtin ? HOOK_PATH | HOOK_BUILTIN : 0; /* Add internal hooks if they are not already in the list */ - ret = hook_list_prepare(&p->hooks, &p->signals, m, p, nullptr); - if (ret) - return ret; + hook_list_prepare(&p->hooks, &p->signals, m, p, nullptr); #endif /* WITH_HOOKS */ /* Initialize pool */ @@ -610,9 +608,7 @@ int path_start(struct path *p) ); #ifdef WITH_HOOKS - ret = hook_list_start(&p->hooks); - if (ret) - return ret; + hook_list_start(&p->hooks); #endif /* WITH_HOOKS */ p->last_sequence = 0; @@ -675,9 +671,7 @@ int path_stop(struct path *p) return ret; #ifdef WITH_HOOKS - ret = hook_list_stop(&p->hooks); - if (ret) - return ret; + hook_list_stop(&p->hooks); #endif /* WITH_HOOKS */ sample_decref(p->last_sample); From 6b2e53feda0974038b6ab88de788e5ce90ad8611 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 11 Jun 2019 18:34:23 +0200 Subject: [PATCH 16/94] path: keep a per path list of mappings --- include/villas/path.h | 1 + lib/path.cpp | 32 ++++++++++++++++---------------- lib/path_source.cpp | 2 +- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/villas/path.h b/include/villas/path.h index 5775c86d0..50eabcf50 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -70,6 +70,7 @@ struct path { struct vlist sources; /**< List of all incoming nodes (struct path_source). */ struct vlist destinations; /**< List of all outgoing nodes (struct path_destination). */ + struct vlist mappings; /**< List of all input mappings (struct mapping_entry). */ struct vlist hooks; /**< List of processing hooks (struct hook). */ struct vlist signals; /**< List of signals which this path creates (struct signal). */ diff --git a/lib/path.cpp b/lib/path.cpp index f2904773d..7e70833d9 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -135,6 +135,10 @@ int path_init(struct path *p) if (ret) return ret; + ret = vlist_init(&p->mappings); + if (ret) + return ret; + #ifdef WITH_HOOKS ret = hook_list_init(&p->hooks); if (ret) @@ -233,6 +237,10 @@ int path_prepare(struct path *p) } /* Initialize sources */ + ret = mapping_list_prepare(&p->mappings); + if (ret) + return ret; + for (size_t i = 0; i < vlist_length(&p->sources); i++) { struct path_source *ps = (struct path_source *) vlist_at(&p->sources, i); @@ -243,10 +251,6 @@ int path_prepare(struct path *p) if (ps->masked) p->mask.set(i); - ret = mapping_list_prepare(&ps->mappings); - if (ret) - return ret; - for (size_t i = 0; i < vlist_length(&ps->mappings); i++) { struct mapping_entry *me = (struct mapping_entry *) vlist_at(&ps->mappings, i); struct vlist *sigs = node_get_signals(me->node, NODE_DIR_IN); @@ -319,10 +323,8 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) const char *mode = nullptr; - struct vlist sources = { .state = STATE_DESTROYED }; struct vlist destinations = { .state = STATE_DESTROYED }; - vlist_init(&sources); vlist_init(&destinations); ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: o, s?: o, s?: b, s?: b, s?: b, s?: i, s?: s, s?: b, s?: F, s?: o, s?: b}", @@ -343,7 +345,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) jerror(&err, "Failed to parse path configuration"); /* Input node(s) */ - ret = mapping_list_parse(&sources, json_in, nodes); + ret = mapping_list_parse(&p->mappings, json_in, nodes); if (ret) { p->logger->error("Failed to parse input mapping of path {}", path_name(p)); return -1; @@ -368,8 +370,8 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) jerror(&err, "Failed to parse output nodes"); } - for (size_t i = 0; i < vlist_length(&sources); i++) { - struct mapping_entry *me = (struct mapping_entry *) vlist_at(&sources, i); + for (size_t i = 0; i < vlist_length(&p->mappings); i++) { + struct mapping_entry *me = (struct mapping_entry *) vlist_at(&p->mappings, i); struct path_source *ps = nullptr; /* Check if there is already a path_source for this source */ @@ -474,9 +476,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) #ifdef WITH_HOOKS if (json_hooks) { - ret = hook_list_parse(&p->hooks, json_hooks, HOOK_PATH, p, nullptr); - if (ret) - return ret; + hook_list_parse(&p->hooks, json_hooks, HOOK_PATH, p, nullptr); } #endif /* WITH_HOOKS */ @@ -490,10 +490,6 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) p->poll = 0; } - ret = vlist_destroy(&sources, nullptr, false); - if (ret) - return ret; - ret = vlist_destroy(&destinations, nullptr, false); if (ret) return ret; @@ -705,6 +701,10 @@ int path_destroy(struct path *p) if (ret) return ret; + ret = vlist_destroy(&p->mappings, nullptr, true); + if (ret) + return ret; + if (p->reader.pfds) free(p->reader.pfds); diff --git a/lib/path_source.cpp b/lib/path_source.cpp index b82378840..4a289ff14 100644 --- a/lib/path_source.cpp +++ b/lib/path_source.cpp @@ -52,7 +52,7 @@ int path_source_destroy(struct path_source *ps) if (ret) return ret; - ret = vlist_destroy(&ps->mappings, nullptr, true); + ret = vlist_destroy(&ps->mappings, nullptr, false); if (ret) return ret; From 7ad5c58d0ee7f3475edea7503f595959c28912c2 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 11 Jun 2019 16:41:33 +0000 Subject: [PATCH 17/94] exec: start executable in exec_prepare() rather than exec_start() --- lib/nodes/exec.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index 158ae93a9..7d7623947 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -74,6 +74,10 @@ int exec_prepare(struct node *n) if (ret) return ret; + /* Start subprocess */ + e->proc = std::make_unique(e->command); + debug(2, "Started sub-process with pid=%d", e->proc->getPid()); + return 0; } @@ -91,11 +95,7 @@ int exec_destroy(struct node *n) int exec_start(struct node *n) { - struct exec *e = (struct exec *) n->_vd; - - /* Start subprocess */ - e->proc = std::make_unique(e->command); - debug(2, "Started sub-process with pid=%d", e->proc->getPid()); +// struct exec *e = (struct exec *) n->_vd; return 0; } From 2e6ca2de9499fe855dc187d7defe176ea1fb985d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 18 Jun 2019 17:52:54 +0200 Subject: [PATCH 18/94] avoid calling copy constructors --- clients/shmem/villas-shmem.cpp | 2 +- src/villas-conf2json.cpp | 2 +- src/villas-convert.cpp | 2 +- src/villas-hook.cpp | 2 +- src/villas-node.cpp | 2 +- src/villas-pipe.cpp | 2 +- src/villas-relay.cpp | 2 +- src/villas-signal.cpp | 2 +- src/villas-test-cmp.cpp | 2 +- src/villas-test-config.cpp | 2 +- src/villas-test-rtt.cpp | 2 +- src/villas-zmq-keygen.cpp | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clients/shmem/villas-shmem.cpp b/clients/shmem/villas-shmem.cpp index e4885d9b5..f5b022d6f 100644 --- a/clients/shmem/villas-shmem.cpp +++ b/clients/shmem/villas-shmem.cpp @@ -138,7 +138,7 @@ protected: int main(int argc, char *argv[]) { - auto t = villas::node::tools::Shmem(argc, argv); + villas::node::tools::Shmem t(argc, argv); return t.run(); } diff --git a/src/villas-conf2json.cpp b/src/villas-conf2json.cpp index 49e040e75..e16e9c53e 100644 --- a/src/villas-conf2json.cpp +++ b/src/villas-conf2json.cpp @@ -99,7 +99,7 @@ protected: int main(int argc, char *argv[]) { - auto t = villas::node::tools::Config2Json(argc, argv); + villas::node::tools::Config2Json t(argc, argv); return t.run(); } diff --git a/src/villas-convert.cpp b/src/villas-convert.cpp index ee66a18b2..29e467ebb 100644 --- a/src/villas-convert.cpp +++ b/src/villas-convert.cpp @@ -177,7 +177,7 @@ protected: int main(int argc, char *argv[]) { - auto t = villas::node::tools::Convert(argc, argv); + villas::node::tools::Convert t(argc, argv); return t.run(); } diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index 0967ba9e8..0d80445c3 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -316,7 +316,7 @@ stop: sent = io_print(&io, smps, send); int main(int argc, char *argv[]) { - auto t = villas::node::tools::Hook(argc, argv); + villas::node::tools::Hook t(argc, argv); return t.run(); } diff --git a/src/villas-node.cpp b/src/villas-node.cpp index 963223145..2de248b35 100644 --- a/src/villas-node.cpp +++ b/src/villas-node.cpp @@ -206,7 +206,7 @@ protected: int main(int argc, char *argv[]) { - auto t = villas::node::tools::Node(argc, argv); + villas::node::tools::Node t(argc, argv); return t.run(); } diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index c27c67b8c..eb12a146a 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -504,7 +504,7 @@ check: if (optarg == endptr) int main(int argc, char *argv[]) { - auto t = villas::node::tools::Pipe(argc, argv); + villas::node::tools::Pipe t(argc, argv); return t.run(); } diff --git a/src/villas-relay.cpp b/src/villas-relay.cpp index 31cc660fd..b817837e7 100644 --- a/src/villas-relay.cpp +++ b/src/villas-relay.cpp @@ -529,7 +529,7 @@ const lws_http_mount Relay::mount = { int main(int argc, char *argv[]) { - auto t = villas::node::tools::Relay(argc, argv); + villas::node::tools::Relay t(argc, argv); return t.run(); } diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 4079c6a37..8abce4e7f 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -328,7 +328,7 @@ out: sample_decref(t); int main(int argc, char *argv[]) { - auto t = villas::node::tools::Signal(argc, argv); + villas::node::tools::Signal t(argc, argv); return t.run(); } diff --git a/src/villas-test-cmp.cpp b/src/villas-test-cmp.cpp index f06bfc5fe..8700cbfad 100644 --- a/src/villas-test-cmp.cpp +++ b/src/villas-test-cmp.cpp @@ -286,7 +286,7 @@ out: for (auto side : sides) int main(int argc, char *argv[]) { - auto t = villas::node::tools::TestCmp(argc, argv); + villas::node::tools::TestCmp t(argc, argv); return t.run(); } diff --git a/src/villas-test-config.cpp b/src/villas-test-config.cpp index 86fb50e15..c1b697ed7 100644 --- a/src/villas-test-config.cpp +++ b/src/villas-test-config.cpp @@ -115,7 +115,7 @@ protected: int main(int argc, char *argv[]) { - auto t = villas::node::tools::TestConfig(argc, argv); + villas::node::tools::TestConfig t(argc, argv); return t.run(); } diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index 3d9d6021d..391f56dbf 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -260,7 +260,7 @@ check: if (optarg == endptr) int main(int argc, char *argv[]) { - auto t = villas::node::tools::TestRtt(argc, argv); + villas::node::tools::TestRtt t(argc, argv); return t.run(); } diff --git a/src/villas-zmq-keygen.cpp b/src/villas-zmq-keygen.cpp index 2c0bb124e..4dbd0a566 100644 --- a/src/villas-zmq-keygen.cpp +++ b/src/villas-zmq-keygen.cpp @@ -79,7 +79,7 @@ protected: int main(int argc, char *argv[]) { - auto t = villas::node::tools::ZmqKeygen(argc, argv); + villas::node::tools::ZmqKeygen t(argc, argv); return t.run(); } From 51259b97016ac1a12939a11a06212ba1724d3e87 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 18 Jun 2019 18:50:24 +0100 Subject: [PATCH 19/94] villas-signal: fix initialization order --- src/villas-signal.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 8abce4e7f..ad7a5a83b 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -258,18 +258,10 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to verify node configuration"); - ret = pool_init(&q, 16, SAMPLE_LENGTH(vlist_length(&n.in.signals)), &memory_heap); - if (ret) - throw RuntimeError("Failed to initialize pool"); - ret = node_prepare(&n); if (ret) throw RuntimeError("Failed to start node {}: reason={}", node_name(&n), ret); - ret = node_start(&n); - if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(&n), ret); - ret = io_init(&io, ft, &n.in.signals, IO_FLUSH | (SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET)); if (ret) throw RuntimeError("Failed to initialize output"); @@ -278,10 +270,18 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to validate IO configuration"); + ret = pool_init(&q, 16, SAMPLE_LENGTH(vlist_length(&n.in.signals)), &memory_heap); + if (ret) + throw RuntimeError("Failed to initialize pool"); + ret = io_open(&io, nullptr); if (ret) throw RuntimeError("Failed to open output"); + ret = node_start(&n); + if (ret) + throw RuntimeError("Failed to start node {}: reason={}", node_name(&n), ret); + while (!stop && n.state == STATE_STARTED) { t = sample_alloc(&q); From 73677d0df692574459adc2dcf9ef3bf4a0c0c4c6 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 18 Jun 2019 18:51:52 +0100 Subject: [PATCH 20/94] infiniband: fix printf formatting string on arm arch --- lib/nodes/infiniband.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/nodes/infiniband.cpp b/lib/nodes/infiniband.cpp index a2a49c650..6d68f65af 100644 --- a/lib/nodes/infiniband.cpp +++ b/lib/nodes/infiniband.cpp @@ -20,8 +20,9 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include +#include #include #include @@ -832,7 +833,7 @@ int ib_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *relea ret = ibv_post_recv(ib->ctx.id->qp, &wr[0], &bad_wr); if (ret) - error("Was unable to post receive WR in node %s: %i, bad WR ID: 0x%lx", + error("Was unable to post receive WR in node %s: %i, bad WR ID: 0x%" PRIu64, node_name(n), ret, bad_wr->wr_id); debug(LOG_IB | 10, "Succesfully posted receive Work Requests"); @@ -961,7 +962,7 @@ int ib_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *rele /* The remaining work requests will be bad. Ripple through list * and prepare them to be released */ - debug(LOG_IB | 4, "Bad WR occured with ID: 0x%zx and S/G address: 0x%px: %i", + debug(LOG_IB | 4, "Bad WR occured with ID: 0x%" PRIu64 " and S/G address: 0x%px: %i", bad_wr->wr_id, bad_wr->sg_list, ret); while (1) { From f2776109c5dab9b6baca65ce9eb3e126126ebe1c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 18 Jun 2019 18:52:51 +0100 Subject: [PATCH 21/94] python: fix invalid relative import for Python 3.5 --- python/villas/node/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/villas/node/__init__.py b/python/villas/node/__init__.py index 5dd9dac99..e69de29bb 100644 --- a/python/villas/node/__init__.py +++ b/python/villas/node/__init__.py @@ -1 +0,0 @@ -from . import node From 2a7d876f7c3d17dd886a7da7ceee944271e63eab Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 20 Jun 2019 09:50:14 +0200 Subject: [PATCH 22/94] test-cmp: fix initialisation order --- src/villas-test-cmp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/villas-test-cmp.cpp b/src/villas-test-cmp.cpp index 8700cbfad..fdd7544e7 100644 --- a/src/villas-test-cmp.cpp +++ b/src/villas-test-cmp.cpp @@ -218,15 +218,15 @@ check: if (optarg == endptr) if (!fmt) throw RuntimeError("Invalid IO format: {}", format); + ret = pool_init(&pool, filenames.size(), SAMPLE_LENGTH(DEFAULT_SAMPLE_LENGTH), &memory_heap); + if (ret) + throw RuntimeError("Failed to initialize pool"); + /* Open files */ std::vector sides; for (auto filename : filenames) sides.push_back(new TestCmpSide(filename, fmt, dtypes, &pool)); - ret = pool_init(&pool, sides.size(), SAMPLE_LENGTH(DEFAULT_SAMPLE_LENGTH), &memory_heap); - if (ret) - throw RuntimeError("Failed to initialize pool"); - line = 0; for (;;) { /* Read next sample from all files */ From f05b2ae9528232bcefe4691cc5a3d350c85b6d10 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 10:51:26 +0200 Subject: [PATCH 23/94] exec: add support for env variables, working directory. non-shell mode --- common | 2 +- etc/examples/nodes/exec.conf | 7 ++- include/villas/nodes/exec.hpp | 4 ++ lib/nodes/exec.cpp | 79 +++++++++++++++++++++---- tests/integration/pipe-loopback-exec.sh | 2 +- 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/common b/common index 7215f711a..719ad763c 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 7215f711a80bf1dde1059925417b0591589be448 +Subproject commit 719ad763cce242e418b82b63bf596dfccb6c725b diff --git a/etc/examples/nodes/exec.conf b/etc/examples/nodes/exec.conf index 75e3c86ad..aee5328fc 100644 --- a/etc/examples/nodes/exec.conf +++ b/etc/examples/nodes/exec.conf @@ -3,6 +3,11 @@ nodes = { type = "exec" format = "villas.human" flush = true - exec = "tee test" + exec = [ "tee test" ] + shell = true + working_directory = "/tmp" + environment = { + MYVAR = "TESTVAL" + } } } diff --git a/include/villas/nodes/exec.hpp b/include/villas/nodes/exec.hpp index adae7f101..5b5cc9c5a 100644 --- a/include/villas/nodes/exec.hpp +++ b/include/villas/nodes/exec.hpp @@ -44,7 +44,11 @@ struct exec { std::unique_ptr proc; bool flush; + bool shell; + std::string working_dir; std::string command; + villas::utils::Popen::arg_list arguments; + villas::utils::Popen::env_map environment; struct format_type *format; struct io io; }; diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index 7d7623947..dea9ec1fa 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -26,7 +26,9 @@ #include #include #include +#include +using namespace villas; using namespace villas::utils; int exec_parse(struct node *n, json_t *cfg) @@ -36,26 +38,79 @@ int exec_parse(struct node *n, json_t *cfg) json_error_t err; int ret, flush = 0; - const char *command; - const char *format = "villas.human"; + json_t *json_exec; + json_t *json_env = nullptr; - ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s?: s, s?: b }", - "exec", &command, + const char *wd = nullptr; + const char *format = "villas.human"; + int shell = -1; + + ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: s, s?: b, s?: o, s?: b, s?: s }", + "exec", &json_exec, "format", &format, - "flush", &flush + "flush", &flush, + "environment", &json_env, + "shell", &shell, + "working_directory", &wd ); if (ret) - jerror(&err, "Failed to parse configuration of node %s", node_name(n)); + throw ConfigError(cfg, err, "node-config-node-exec"); - e->command = command; e->flush = flush; + e->shell = shell < 0 ? json_is_string(json_exec) : shell; + + e->arguments.clear(); + e->environment.clear(); + + if (json_is_string(json_exec)) { + if (shell == 0) + throw ConfigError(json_exec, "node-config-node-exec-shell", "The exec setting must be an array if shell mode is disabled."); + + e->command = json_string_value(json_exec); + } + else if (json_is_array(json_exec)) { + if (shell == 1) + throw ConfigError(json_exec, "node-config-node-exec-shell", "The exec setting must be a string if shell mode is enabled."); + + if (json_array_size(json_exec) < 1) + throw ConfigError(json_exec, "node-config-node-exec-exec", "At least one argument must be given"); + + size_t i; + json_t *json_arg; + json_array_foreach(json_exec, i, json_arg) { + if (!json_is_string(json_arg)) + throw ConfigError(json_arg, "node-config-node-exec-exec", "All arguments must be of string type"); + + if (i == 0) + e->command = json_string_value(json_arg); + else + e->arguments.push_back(json_string_value(json_arg)); + } + } + + if (json_env) { + /* obj is a JSON object */ + const char *key; + json_t *json_value; + + json_object_foreach(json_env, key, json_value) { + if (!json_is_string(json_value)) + throw ConfigError(json_value, "node-config-node-exec-environment", "Environment variables must be of string type"); + + e->environment[key] = json_string_value(json_value); + } + } e->format = format_type_lookup(format); - if (!e->format) - error("Invalid format '%s' for node %s", format, node_name(n)); + if (!e->format) { + json_t *json_format = json_object_get(cfg, "format"); + throw ConfigError(json_format, "node-config-node-exec-format", "Invalid format: {)", format); + } - if (!(e->format->flags & IO_NEWLINES)) - error("The exec node-type currently supports only line-delimited formats"); + if (!(e->format->flags & IO_NEWLINES)) { + json_t *json_format = json_object_get(cfg, "format"); + throw ConfigError(json_format, "node-config-node-exec-format", "Only line-delimited formats are currently supported"); + } return 0; } @@ -75,7 +130,7 @@ int exec_prepare(struct node *n) return ret; /* Start subprocess */ - e->proc = std::make_unique(e->command); + e->proc = std::make_unique(e->command, e->arguments, e->environment, e->working_dir, e->shell); debug(2, "Started sub-process with pid=%d", e->proc->getPid()); return 0; diff --git a/tests/integration/pipe-loopback-exec.sh b/tests/integration/pipe-loopback-exec.sh index 7dba94358..f5ddd9934 100755 --- a/tests/integration/pipe-loopback-exec.sh +++ b/tests/integration/pipe-loopback-exec.sh @@ -44,7 +44,7 @@ cat > ${CONFIG_FILE} << EOF "type" : "exec", "format" : "${FORMAT}", - "command" : "cat" + "exec" : "cat" } } } From c842914bc563f7f7a0bdb9cce1f6058f35eadd11 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 13:35:42 +0200 Subject: [PATCH 24/94] stats: port to C++ --- include/villas/mapping.h | 6 +- include/villas/node.h | 3 +- include/villas/nodes/stats.hpp | 6 +- include/villas/stats.h | 120 --------------- include/villas/stats.hpp | 132 ++++++++++++++++ lib/api/actions/nodes.cpp | 4 +- lib/api/actions/stats.cpp | 4 +- lib/hooks/stats.cpp | 49 +++--- lib/mapping.cpp | 16 +- lib/node.cpp | 3 +- lib/nodes/rtp.cpp | 9 +- lib/nodes/stats.cpp | 26 ++-- lib/signal.cpp | 3 +- lib/stats.cpp | 268 +++++++++++++++------------------ lib/super_node.cpp | 2 +- tests/unit/mapping.cpp | 10 +- 16 files changed, 318 insertions(+), 343 deletions(-) delete mode 100644 include/villas/stats.h create mode 100644 include/villas/stats.hpp diff --git a/include/villas/mapping.h b/include/villas/mapping.h index eb816b76b..6859109de 100644 --- a/include/villas/mapping.h +++ b/include/villas/mapping.h @@ -25,7 +25,7 @@ #include -#include +#include #include /* Forward declarations */ @@ -70,8 +70,8 @@ struct mapping_entry { } data; struct { - enum stats_metric metric; - enum stats_type type; + enum villas::Stats::Metric metric; + enum villas::Stats::Type type; } stats; struct { diff --git a/include/villas/node.h b/include/villas/node.h index 1b831ad72..955986912 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #if defined(LIBNL3_ROUTE_FOUND) && defined(__linux__) @@ -67,7 +68,7 @@ struct node { uint64_t sequence; /**< This is a counter of received samples, in case the node-type does not generate sequence numbers itself. */ - struct stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ + villas::Stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ struct node_direction in, out; diff --git a/include/villas/nodes/stats.hpp b/include/villas/nodes/stats.hpp index 612c1ae03..27a507397 100644 --- a/include/villas/nodes/stats.hpp +++ b/include/villas/nodes/stats.hpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include @@ -40,8 +40,8 @@ struct stats_node_signal { struct node *node; char *node_str; - enum stats_metric metric; - enum stats_type type; + enum villas::Stats::Metric metric; + enum villas::Stats::Type type; }; struct stats_node { diff --git a/include/villas/stats.h b/include/villas/stats.h deleted file mode 100644 index 231398f60..000000000 --- a/include/villas/stats.h +++ /dev/null @@ -1,120 +0,0 @@ -/** Statistic collection. - * - * @file - * @author Steffen Vogel - * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASnode - * - * 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 - * 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 . - *********************************************************************************/ - -#pragma once - -#include -#include - -#include -#include -#include - -/* Forward declarations */ -struct sample; -struct node; - -enum stats_format { - STATS_FORMAT_HUMAN, - STATS_FORMAT_JSON, - STATS_FORMAT_MATLAB -}; - -enum stats_metric { - STATS_METRIC_INVALID = -1, - - STATS_METRIC_SMPS_SKIPPED, /**< Counter for skipped samples due to hooks. */ - STATS_METRIC_SMPS_REORDERED, /**< Counter for reordered samples. */ - - /* Timings */ - STATS_METRIC_GAP_SAMPLE, /**< Histogram for inter sample timestamps (as sent by remote). */ - STATS_METRIC_GAP_RECEIVED, /**< Histogram for inter sample arrival time (as seen by this instance). */ - STATS_METRIC_OWD, /**< Histogram for one-way-delay (OWD) of received samples. */ - STATS_METRIC_AGE, /**< Processing time of packets within VILLASnode. */ - - /* RTP metrics */ - STATS_METRIC_RTP_LOSS_FRACTION, /**< Fraction lost since last RTP SR/RR. */ - STATS_METRIC_RTP_PKTS_LOST, /**< Cumul. no. pkts lost. */ - STATS_METRIC_RTP_JITTER, /**< Interarrival jitter. */ - - /* Always last */ - STATS_METRIC_COUNT /**< Just here to have an updated number of statistics. */ -}; - -enum stats_type { - STATS_TYPE_INVALID = -1, - STATS_TYPE_LAST, - STATS_TYPE_HIGHEST, - STATS_TYPE_LOWEST, - STATS_TYPE_MEAN, - STATS_TYPE_VAR, - STATS_TYPE_STDDEV, - STATS_TYPE_TOTAL, - STATS_TYPE_COUNT -}; - -struct stats_metric_description { - const char *name; - enum stats_metric metric; - const char *unit; - const char *desc; -}; - -struct stats_type_description { - const char *name; - enum stats_type type; - enum signal_type signal_type; -}; - -struct stats { - enum state state; - villas::Hist histograms[STATS_METRIC_COUNT]; -}; - -extern struct stats_metric_description stats_metrics[]; -extern struct stats_type_description stats_types[]; - -int stats_lookup_format(const char *str); - -enum stats_metric stats_lookup_metric(const char *str); - -enum stats_type stats_lookup_type(const char *str); - -int stats_init(struct stats *s, int buckets, int warmup); - -int stats_destroy(struct stats *s); - -void stats_update(struct stats *s, enum stats_metric id, double val); - -json_t * stats_json(struct stats *s); - -void stats_reset(struct stats *s); - -void stats_print_header(enum stats_format fmt); - -void stats_print_periodic(struct stats *s, FILE *f, enum stats_format fmt, struct node *p); - -void stats_print(struct stats *s, FILE *f, enum stats_format fmt, int verbose); - -union signal_data stats_get_value(const struct stats *s, enum stats_metric sm, enum stats_type st); - diff --git a/include/villas/stats.hpp b/include/villas/stats.hpp new file mode 100644 index 000000000..65128b63f --- /dev/null +++ b/include/villas/stats.hpp @@ -0,0 +1,132 @@ +/** Statistic collection. + * + * @file + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/* Forward declarations */ +struct sample; +struct node; + +namespace villas { + +class Stats { + +public: + enum class Format { + HUMAN, + JSON, + MATLAB + }; + + enum class Metric { + SMPS_SKIPPED, /**< Counter for skipped samples due to hooks. */ + SMPS_REORDERED, /**< Counter for reordered samples. */ + + /* Timings */ + GAP_SAMPLE, /**< Histogram for inter sample timestamps (as sent by remote). */ + GAP_RECEIVED, /**< Histogram for inter sample arrival time (as seen by this instance). */ + OWD, /**< Histogram for one-way-delay (OWD) of received samples. */ + AGE, /**< Processing time of packets within VILLASnode. */ + + /* RTP metrics */ + RTP_LOSS_FRACTION, /**< Fraction lost since last RTP SR/RR. */ + RTP_PKTS_LOST, /**< Cumul. no. pkts lost. */ + RTP_JITTER /**< Interarrival jitter. */ + }; + + enum class Type { + LAST, + HIGHEST, + LOWEST, + MEAN, + VAR, + STDDEV, + TOTAL + }; + +protected: + std::unordered_map histograms; + + struct MetricDescription { + const char *name; + const char *unit; + const char *desc; + }; + + struct TypeDescription { + const char *name; + enum signal_type signal_type; + }; + + static std::shared_ptr table; + + static void setupTable(); + +public: + + Stats(int buckets, int warmup); + + static + enum Format lookupFormat(const std::string &str); + + static + enum Metric lookupMetric(const std::string &str); + + static + enum Type lookupType(const std::string &str); + + void update(enum Metric id, double val); + + void reset(); + + json_t * toJson() const; + + static + void printHeader(enum Format fmt); + + void printPeriodic(FILE *f, enum Format fmt, struct node *p) const; + + void print(FILE *f, enum Format fmt, int verbose) const; + + union signal_data getValue(enum Metric sm, enum Type st) const; + + const villas::Hist & getHistogram(enum Metric sm) const; + + static std::unordered_map metrics; + static std::unordered_map types; + static std::vector columns; +}; + +} /* namespace villas */ diff --git a/lib/api/actions/nodes.cpp b/lib/api/actions/nodes.cpp index d1b6f0359..1e81d7e7e 100644 --- a/lib/api/actions/nodes.cpp +++ b/lib/api/actions/nodes.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -58,7 +58,7 @@ public: ); if (n->stats) - json_object_set_new(json_node, "stats", stats_json(n->stats)); + json_object_set_new(json_node, "stats", n->stats->toJson()); /* Add all additional fields of node here. * This can be used for metadata */ diff --git a/lib/api/actions/stats.cpp b/lib/api/actions/stats.cpp index 1e251d18b..f2a2c6d4e 100644 --- a/lib/api/actions/stats.cpp +++ b/lib/api/actions/stats.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -58,7 +58,7 @@ public: if (n->stats) { if (reset) { - stats_reset(n->stats); + n->stats->reset(); info("Stats resetted for node %s", node_name(n)); } } diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp index 258ddef5a..21708efa5 100644 --- a/lib/hooks/stats.cpp +++ b/lib/hooks/stats.cpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -53,11 +53,11 @@ public: virtual int process(sample *smp) { - stats *s = node->stats; + Stats *s = node->stats; timespec now = time_now(); - stats_update(s, STATS_METRIC_AGE, time_delta(&smp->ts.received, &now)); + s->update(Stats::Metric::AGE, time_delta(&smp->ts.received, &now)); return HOOK_OK; } @@ -96,22 +96,22 @@ public: virtual int process(sample *smp) { - stats *s = node->stats; + Stats *s = node->stats; if (last) { if (smp->flags & last->flags & SAMPLE_HAS_TS_RECEIVED) - stats_update(s, STATS_METRIC_GAP_RECEIVED, time_delta(&last->ts.received, &smp->ts.received)); + s->update(Stats::Metric::GAP_RECEIVED, time_delta(&last->ts.received, &smp->ts.received)); if (smp->flags & last->flags & SAMPLE_HAS_TS_ORIGIN) - stats_update(s, STATS_METRIC_GAP_SAMPLE, time_delta(&last->ts.origin, &smp->ts.origin)); + s->update(Stats::Metric::GAP_SAMPLE, time_delta(&last->ts.origin, &smp->ts.origin)); if ((smp->flags & SAMPLE_HAS_TS_ORIGIN) && (smp->flags & SAMPLE_HAS_TS_RECEIVED)) - stats_update(s, STATS_METRIC_OWD, time_delta(&smp->ts.origin, &smp->ts.received)); + s->update(Stats::Metric::OWD, time_delta(&smp->ts.origin, &smp->ts.received)); if (smp->flags & last->flags & SAMPLE_HAS_SEQUENCE) { int dist = smp->sequence - (int32_t) last->sequence; if (dist != 1) - stats_update(s, STATS_METRIC_SMPS_REORDERED, dist); + s->update(Stats::Metric::SMPS_REORDERED, dist); } } @@ -129,12 +129,12 @@ public: class StatsHook : public Hook { protected: - struct stats stats; + Stats stats; StatsReadHook *readHook; StatsWriteHook *writeHook; - enum stats_format format; + enum Stats::Format format; int verbose; int warmup; int buckets; @@ -146,20 +146,14 @@ public: StatsHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : Hook(p, n, fl, prio, en), - format(STATS_FORMAT_HUMAN), + stats(buckets, warmup), + format(Stats::Format::HUMAN), verbose(0), warmup(500), buckets(20), output(nullptr), uri(nullptr) { - int ret; - - stats.state = STATE_DESTROYED; - ret = stats_init(&stats, buckets, warmup); - if (ret) - throw RuntimeError("Failed to initialize stats"); - /* Register statistic object to path. * * This allows the path code to update statistics. */ @@ -178,8 +172,7 @@ public: if (uri) free(uri); - if (stats.state != STATE_DESTROYED) - stats_destroy(&stats); + stats.~Stats(); } virtual void start() @@ -199,7 +192,7 @@ public: { assert(state == STATE_STARTED); - stats_print(&stats, uri ? output->file : stdout, format, verbose); + stats.print(uri ? output->file : stdout, format, verbose); if (uri) afclose(output); @@ -211,19 +204,19 @@ public: { assert(state == STATE_STARTED); - stats_reset(&stats); + stats.reset(); } virtual void periodic() { assert(state == STATE_STARTED); - stats_print_periodic(&stats, uri ? output->file : stdout, format, node); + stats.printPeriodic(uri ? output->file : stdout, format, node); } virtual void parse(json_t *cfg) { - int ret, fmt; + int ret; json_error_t err; assert(state != STATE_STARTED); @@ -242,11 +235,11 @@ public: throw ConfigError(cfg, err, "node-config-hook-stats"); if (f) { - fmt = stats_lookup_format(f); - if (fmt < 0) + try { + format = Stats::lookupFormat(f); + } catch (std::invalid_argument &e) { throw ConfigError(cfg, "node-config-hook-stats", "Invalid statistic output format: {}", f); - - format = static_cast(fmt); + } } if (u) diff --git a/lib/mapping.cpp b/lib/mapping.cpp index 45e77e8fc..8e00a251f 100644 --- a/lib/mapping.cpp +++ b/lib/mapping.cpp @@ -29,6 +29,7 @@ #include #include +using namespace villas; using namespace villas::utils; int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *nodes) @@ -76,13 +77,8 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n if (!type) goto invalid_format; - me->stats.metric = stats_lookup_metric(metric); - if (me->stats.metric < 0) - goto invalid_format; - - me->stats.type = stats_lookup_type(type); - if (me->stats.type < 0) - goto invalid_format; + me->stats.metric = Stats::lookupMetric(metric); + me->stats.type = Stats::lookupType(type); } else if (!strcmp(type, "hdr")) { me->type = MAPPING_TYPE_HEADER; @@ -245,7 +241,7 @@ int mapping_update(const struct mapping_entry *me, struct sample *remapped, cons switch (me->type) { case MAPPING_TYPE_STATS: - remapped->data[me->offset] = stats_get_value(me->node->stats, me->stats.metric, me->stats.type); + remapped->data[me->offset] = me->node->stats->getValue(me->stats.metric, me->stats.type); break; case MAPPING_TYPE_TIMESTAMP: { @@ -350,8 +346,8 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str) switch (me->type) { case MAPPING_TYPE_STATS: strcatf(str, "stats.%s.%s", - stats_metrics[me->stats.metric].name, - stats_types[me->stats.type].name + Stats::metrics[me->stats.metric].name, + Stats::types[me->stats.type].name ); break; diff --git a/lib/node.cpp b/lib/node.cpp index a2b9bbd94..7b78e007c 100644 --- a/lib/node.cpp +++ b/lib/node.cpp @@ -43,6 +43,7 @@ #include #endif /* WITH_NETEM */ +using namespace villas; using namespace villas::utils; int node_init(struct node *n, struct node_type *vt) @@ -427,7 +428,7 @@ int node_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *rel int skipped = nread - rread; if (skipped > 0 && n->stats != nullptr) { - stats_update(n->stats, STATS_METRIC_SMPS_SKIPPED, skipped); + n->stats->update(Stats::Metric::SMPS_SKIPPED, skipped); } debug(LOG_NODE | 5, "Received %u samples from node %s of which %d have been skipped", nread, node_name(n), skipped); diff --git a/lib/nodes/rtp.cpp b/lib/nodes/rtp.cpp index 4a2cbc2db..d7ea79a32 100644 --- a/lib/nodes/rtp.cpp +++ b/lib/nodes/rtp.cpp @@ -42,7 +42,7 @@ extern "C" { #include #include #include -#include +#include #include #include #include @@ -53,6 +53,7 @@ extern "C" { static pthread_t re_pthread; +using namespace villas; using namespace villas::node; using namespace villas::utils; @@ -300,9 +301,9 @@ static void rtcp_handler(const struct sa *src, struct rtcp_msg *msg, void *arg) rtp_aimd(n, loss_frac); if (n->stats) { - stats_update(n->stats, STATS_METRIC_RTP_PKTS_LOST, rr->lost); - stats_update(n->stats, STATS_METRIC_RTP_LOSS_FRACTION, loss_frac); - stats_update(n->stats, STATS_METRIC_RTP_JITTER, rr->jitter); + n->stats->update(Stats::Metric::RTP_PKTS_LOST, rr->lost); + n->stats->update(Stats::Metric::RTP_LOSS_FRACTION, loss_frac); + n->stats->update(Stats::Metric::RTP_JITTER, rr->jitter); } r->logger->info("RTCP: rr: num_rrs={}, loss_frac={}, pkts_lost={}, jitter={}", r->rtcp.num_rrs, loss_frac, rr->lost, rr->jitter); diff --git a/lib/nodes/stats.cpp b/lib/nodes/stats.cpp index d1ee7db6d..55316bf35 100644 --- a/lib/nodes/stats.cpp +++ b/lib/nodes/stats.cpp @@ -25,13 +25,12 @@ #include #include #include -#include +#include #include #include #include -#define STATS_METRICS 6 - +using namespace villas; using namespace villas::node; using namespace villas::utils; @@ -72,13 +71,8 @@ int stats_node_signal_parse(struct stats_node_signal *s, json_t *cfg) if (!type) goto invalid_format; - s->metric = stats_lookup_metric(metric); - if (s->metric < 0) - goto invalid_format; - - s->type = stats_lookup_type(type); - if (s->type < 0) - goto invalid_format; + s->metric = Stats::lookupMetric(metric); + s->type = Stats::lookupType(type); s->node_str = strdup(node); @@ -196,16 +190,16 @@ int stats_node_parse(struct node *n, json_t *cfg) error("Failed to parse statistics signal definition of node %s", node_name(n)); if (!sig->name) { - const char *metric = stats_metrics[stats_sig->metric].name; - const char *type = stats_types[stats_sig->type].name; + const char *metric = Stats::metrics[stats_sig->metric].name; + const char *type = Stats::types[stats_sig->type].name; sig->name = strf("%s.%s.%s", stats_sig->node_str, metric, type); } if (!sig->unit) - sig->unit = strdup(stats_metrics[stats_sig->metric].unit); + sig->unit = strdup(Stats::metrics[stats_sig->metric].unit); - if (sig->type != stats_types[stats_sig->type].signal_type) + if (sig->type != Stats::types[stats_sig->type].signal_type) error("Invalid type for signal %zu in node %s", i, node_name(n)); vlist_push(&s->signals, stats_sig); @@ -226,14 +220,14 @@ int stats_node_read(struct node *n, struct sample *smps[], unsigned cnt, unsigne unsigned len = MIN(vlist_length(&s->signals), smps[0]->capacity); for (size_t i = 0; i < len; i++) { - struct stats *st; + Stats *st; struct stats_node_signal *sig = (struct stats_node_signal *) vlist_at(&s->signals, i); st = sig->node->stats; if (!st) return -1; - smps[0]->data[i] = stats_get_value(st, sig->metric, sig->type); + smps[0]->data[i] = st->getValue(sig->metric, sig->type); } smps[0]->length = len; diff --git a/lib/signal.cpp b/lib/signal.cpp index 3e41fb902..2b42a775d 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -28,6 +28,7 @@ #include #include +using namespace villas; using namespace villas::utils; int signal_init(struct signal *s) @@ -57,7 +58,7 @@ int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, u switch (me->type) { case MAPPING_TYPE_STATS: - s->type = stats_types[me->stats.type].signal_type; + s->type = Stats::types[me->stats.type].signal_type; break; case MAPPING_TYPE_HEADER: diff --git a/lib/stats.cpp b/lib/stats.cpp index c930571fb..557772bc9 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -22,7 +22,7 @@ #include -#include +#include #include #include #include @@ -34,180 +34,155 @@ using namespace villas; using namespace villas::utils; -struct stats_metric_description stats_metrics[] = { - { "skipped", STATS_METRIC_SMPS_SKIPPED, "samples", "Skipped samples and the distance between them" }, - { "reordered", STATS_METRIC_SMPS_REORDERED, "samples", "Reordered samples and the distance between them" }, - { "gap_sent", STATS_METRIC_GAP_SAMPLE, "seconds", "Inter-message timestamps (as sent by remote)" }, - { "gap_received", STATS_METRIC_GAP_RECEIVED, "seconds", "Inter-message arrival time (as received by this instance)" }, - { "owd", STATS_METRIC_OWD, "seconds", "One-way-delay (OWD) of received messages" }, - { "age", STATS_METRIC_AGE, "seconds", "Processing time of packets within the from receive to sent" }, - { "rtp.loss_fraction", STATS_METRIC_RTP_LOSS_FRACTION, "percent", "Fraction lost since last RTP SR/RR." }, - { "rtp.pkts_lost", STATS_METRIC_RTP_PKTS_LOST, "packets", "Cumulative number of packtes lost" }, - { "rtp.jitter", STATS_METRIC_RTP_JITTER, "seconds", "Interarrival jitter" }, +std::unordered_map Stats::metrics = { + { Stats::Metric::SMPS_SKIPPED, { "skipped", "samples", "Skipped samples and the distance between them" }}, + { Stats::Metric::SMPS_REORDERED, { "reordered", "samples", "Reordered samples and the distance between them" }}, + { Stats::Metric::GAP_SAMPLE, { "gap_sent", "seconds", "Inter-message timestamps (as sent by remote)" }}, + { Stats::Metric::GAP_RECEIVED, { "gap_received", "seconds", "Inter-message arrival time (as received by this instance)" }}, + { Stats::Metric::OWD, { "owd", "seconds", "One-way-delay (OWD) of received messages" }}, + { Stats::Metric::AGE, { "age", "seconds", "Processing time of packets within the from receive to sent" }}, + { Stats::Metric::RTP_LOSS_FRACTION, { "rtp.loss_fraction", "percent", "Fraction lost since last RTP SR/RR." }}, + { Stats::Metric::RTP_PKTS_LOST, { "rtp.pkts_lost", "packets", "Cumulative number of packtes lost" }}, + { Stats::Metric::RTP_JITTER, { "rtp.jitter", "seconds", "Interarrival jitter" }}, }; -struct stats_type_description stats_types[] = { - { "last", STATS_TYPE_LAST, SIGNAL_TYPE_FLOAT }, - { "highest", STATS_TYPE_HIGHEST, SIGNAL_TYPE_FLOAT }, - { "lowest", STATS_TYPE_LOWEST, SIGNAL_TYPE_FLOAT }, - { "mean", STATS_TYPE_MEAN, SIGNAL_TYPE_FLOAT }, - { "var", STATS_TYPE_VAR, SIGNAL_TYPE_FLOAT }, - { "stddev", STATS_TYPE_STDDEV, SIGNAL_TYPE_FLOAT }, - { "total", STATS_TYPE_TOTAL, SIGNAL_TYPE_INTEGER } +std::unordered_map Stats::types = { + { Stats::Type::LAST, { "last", SIGNAL_TYPE_FLOAT }}, + { Stats::Type::HIGHEST, { "highest", SIGNAL_TYPE_FLOAT }}, + { Stats::Type::LOWEST, { "lowest", SIGNAL_TYPE_FLOAT }}, + { Stats::Type::MEAN, { "mean", SIGNAL_TYPE_FLOAT }}, + { Stats::Type::VAR, { "var", SIGNAL_TYPE_FLOAT }}, + { Stats::Type::STDDEV, { "stddev", SIGNAL_TYPE_FLOAT }}, + { Stats::Type::TOTAL, { "total", SIGNAL_TYPE_INTEGER }} }; -int stats_lookup_format(const char *str) +std::vector Stats::columns = { + { 10, TableColumn::Alignment::LEFT, "Node", "%s" }, + { 10, TableColumn::Alignment::RIGHT, "Recv", "%ju", "pkts" }, + { 10, TableColumn::Alignment::RIGHT, "Sent", "%ju", "pkts" }, + { 10, TableColumn::Alignment::RIGHT, "Drop", "%ju", "pkts" }, + { 10, TableColumn::Alignment::RIGHT, "Skip", "%ju", "pkts" }, + { 10, TableColumn::Alignment::RIGHT, "OWD last", "%lf", "secs" }, + { 10, TableColumn::Alignment::RIGHT, "OWD mean", "%lf", "secs" }, + { 10, TableColumn::Alignment::RIGHT, "Rate last", "%lf", "pkt/sec" }, + { 10, TableColumn::Alignment::RIGHT, "Rate mean", "%lf", "pkt/sec" }, + { 10, TableColumn::Alignment::RIGHT, "Age mean", "%lf", "secs" }, + { 10, TableColumn::Alignment::RIGHT, "Age Max", "%lf", "sec" } +}; + +enum Stats::Format Stats::lookupFormat(const std::string &str) { - if (!strcmp(str, "human")) - return STATS_FORMAT_HUMAN; - else if (!strcmp(str, "json")) - return STATS_FORMAT_JSON; - else if (!strcmp(str, "matlab")) - return STATS_FORMAT_MATLAB; - else - return -1; + if (str == "human") + return Format::HUMAN; + else if (str == "json") + return Format::JSON; + else if (str == "matlab") + return Format::MATLAB; + + throw std::invalid_argument("Invalid format"); } -enum stats_metric stats_lookup_metric(const char *str) +enum Stats::Metric Stats::lookupMetric(const std::string &str) { - for (int i = 0; i < STATS_METRIC_COUNT; i++) { - struct stats_metric_description *d = &stats_metrics[i]; - - if (!strcmp(str, d->name)) - return d->metric; + for (auto m : metrics) { + if (str == m.second.name) + return m.first; } - return STATS_METRIC_INVALID; + throw std::invalid_argument("Invalid metric"); } -enum stats_type stats_lookup_type(const char *str) +enum Stats::Type Stats::lookupType(const std::string &str) { - for (int i = 0; i < STATS_TYPE_COUNT; i++) { - struct stats_type_description *d = &stats_types[i]; - - if (!strcmp(str, d->name)) - return d->type; + for (auto t : types) { + if (str == t.second.name) + return t.first; } - return STATS_TYPE_INVALID; + throw std::invalid_argument("Invalid type"); } -int stats_init(struct stats *s, int buckets, int warmup) +Stats::Stats(int buckets, int warmup) { - assert(s->state == STATE_DESTROYED); - - for (int i = 0; i < STATS_METRIC_COUNT; i++) - new (&s->histograms[i]) Hist(buckets, warmup); - - s->state = STATE_INITIALIZED; - - return 0; + for (auto m : metrics) + histograms[m.first] = Hist(buckets, warmup); } -int stats_destroy(struct stats *s) +void Stats::update(enum Metric m, double val) { - assert(s->state != STATE_DESTROYED); - - for (int i = 0; i < STATS_METRIC_COUNT; i++) - s->histograms[i].~Hist(); - - s->state = STATE_DESTROYED; - - return 0; + histograms[m].put(val); } -void stats_update(struct stats *s, enum stats_metric id, double val) +void Stats::reset() { - assert(s->state == STATE_INITIALIZED); - - s->histograms[id].put(val); + for (auto m : metrics) + histograms[m.first].reset(); } -json_t * stats_json(struct stats *s) +json_t * Stats::toJson() const { - assert(s->state == STATE_INITIALIZED); - json_t *obj = json_object(); - for (int i = 0; i < STATS_METRIC_COUNT; i++) { - struct stats_metric_description *d = &stats_metrics[i]; - const Hist &h = s->histograms[i]; + for (auto m : metrics) { + const Hist &h = histograms.at(m.first); - json_object_set_new(obj, d->name, h.toJson()); + json_object_set_new(obj, m.second.name, h.toJson()); } return obj; } -void stats_reset(struct stats *s) -{ - assert(s->state == STATE_INITIALIZED); - - for (int i = 0; i < STATS_METRIC_COUNT; i++) - s->histograms[i].reset(); -} - -static std::vector stats_columns = { - { 10, TableColumn::align::LEFT, "Node", "%s" }, - { 10, TableColumn::align::RIGHT, "Recv", "%ju", "pkts" }, - { 10, TableColumn::align::RIGHT, "Sent", "%ju", "pkts" }, - { 10, TableColumn::align::RIGHT, "Drop", "%ju", "pkts" }, - { 10, TableColumn::align::RIGHT, "Skip", "%ju", "pkts" }, - { 10, TableColumn::align::RIGHT, "OWD last", "%lf", "secs" }, - { 10, TableColumn::align::RIGHT, "OWD mean", "%lf", "secs" }, - { 10, TableColumn::align::RIGHT, "Rate last", "%lf", "pkt/sec" }, - { 10, TableColumn::align::RIGHT, "Rate mean", "%lf", "pkt/sec" }, - { 10, TableColumn::align::RIGHT, "Age mean", "%lf", "secs" }, - { 10, TableColumn::align::RIGHT, "Age Max", "%lf", "sec" } -}; - -static Table stats_table = Table(stats_columns); - -void stats_print_header(enum stats_format fmt) +void Stats::printHeader(enum Format fmt) { switch (fmt) { - case STATS_FORMAT_HUMAN: - stats_table.header(); + case Format::HUMAN: + setupTable(); + table->header(); break; default: { } } } -void stats_print_periodic(struct stats *s, FILE *f, enum stats_format fmt, struct node *n) +void Stats::setupTable() { - assert(s->state == STATE_INITIALIZED); + if (!table) + table = std::make_shared
(columns); +} +void Stats::printPeriodic(FILE *f, enum Format fmt, struct node *n) const +{ switch (fmt) { - case STATS_FORMAT_HUMAN: - stats_table.row(11, + case Format::HUMAN: + setupTable(); + table->row(11, node_name_short(n), - (uintmax_t) s->histograms[STATS_METRIC_OWD].getTotal(), - (uintmax_t) s->histograms[STATS_METRIC_AGE].getTotal(), - (uintmax_t) s->histograms[STATS_METRIC_SMPS_REORDERED].getTotal(), - (uintmax_t) s->histograms[STATS_METRIC_SMPS_SKIPPED].getTotal(), - (double) s->histograms[STATS_METRIC_OWD].getLast(), - (double) s->histograms[STATS_METRIC_OWD].getMean(), - (double) 1.0 / s->histograms[STATS_METRIC_GAP_RECEIVED].getLast(), - (double) 1.0 / s->histograms[STATS_METRIC_GAP_RECEIVED].getMean(), - (double) s->histograms[STATS_METRIC_AGE].getMean(), - (double) s->histograms[STATS_METRIC_AGE].getHighest() + (uintmax_t) histograms.at(Metric::OWD).getTotal(), + (uintmax_t) histograms.at(Metric::AGE).getTotal(), + (uintmax_t) histograms.at(Metric::SMPS_REORDERED).getTotal(), + (uintmax_t) histograms.at(Metric::SMPS_SKIPPED).getTotal(), + (double) histograms.at(Metric::OWD).getLast(), + (double) histograms.at(Metric::OWD).getMean(), + (double) 1.0 / histograms.at(Metric::GAP_RECEIVED).getLast(), + (double) 1.0 / histograms.at(Metric::GAP_RECEIVED).getMean(), + (double) histograms.at(Metric::AGE).getMean(), + (double) histograms.at(Metric::AGE).getHighest() ); break; - case STATS_FORMAT_JSON: { + case Format::JSON: { json_t *json_stats = json_pack("{ s: s, s: i, s: i, s: i, s: i, s: f, s: f, s: f, s: f, s: f, s: f }", "node", node_name(n), - "recv", s->histograms[STATS_METRIC_OWD].getTotal(), - "sent", s->histograms[STATS_METRIC_AGE].getTotal(), - "dropped", s->histograms[STATS_METRIC_SMPS_REORDERED].getTotal(), - "skipped", s->histograms[STATS_METRIC_SMPS_SKIPPED].getTotal(), - "owd_last", 1.0 / s->histograms[STATS_METRIC_OWD].getLast(), - "owd_mean", 1.0 / s->histograms[STATS_METRIC_OWD].getMean(), - "rate_last", 1.0 / s->histograms[STATS_METRIC_GAP_SAMPLE].getLast(), - "rate_mean", 1.0 / s->histograms[STATS_METRIC_GAP_SAMPLE].getMean(), - "age_mean", s->histograms[STATS_METRIC_AGE].getMean(), - "age_max", s->histograms[STATS_METRIC_AGE].getHighest() + "recv", histograms.at(Metric::OWD).getTotal(), + "sent", histograms.at(Metric::AGE).getTotal(), + "dropped", histograms.at(Metric::SMPS_REORDERED).getTotal(), + "skipped", histograms.at(Metric::SMPS_SKIPPED).getTotal(), + "owd_last", 1.0 / histograms.at(Metric::OWD).getLast(), + "owd_mean", 1.0 / histograms.at(Metric::OWD).getMean(), + "rate_last", 1.0 / histograms.at(Metric::GAP_SAMPLE).getLast(), + "rate_mean", 1.0 / histograms.at(Metric::GAP_SAMPLE).getMean(), + "age_mean", histograms.at(Metric::AGE).getMean(), + "age_max", histograms.at(Metric::AGE).getHighest() ); json_dumpf(json_stats, f, 0); break; @@ -217,64 +192,56 @@ void stats_print_periodic(struct stats *s, FILE *f, enum stats_format fmt, struc } } -void stats_print(struct stats *s, FILE *f, enum stats_format fmt, int verbose) +void Stats::print(FILE *f, enum Format fmt, int verbose) const { - assert(s->state == STATE_INITIALIZED); - switch (fmt) { - case STATS_FORMAT_HUMAN: - for (int i = 0; i < STATS_METRIC_COUNT; i++) { - struct stats_metric_description *d = &stats_metrics[i]; - - info("%s: %s", d->name, d->desc); - s->histograms[i].print(verbose); + case Format::HUMAN: + for (auto m : metrics) { + info("%s: %s", m.second.name, m.second.desc); + histograms.at(m.first).print(verbose); } break; - case STATS_FORMAT_JSON: { - json_t *json_stats = stats_json(s); - json_dumpf(json_stats, f, 0); + case Format::JSON: + json_dumpf(toJson(), f, 0); fflush(f); break; - } default: { } } } -union signal_data stats_get_value(const struct stats *s, enum stats_metric sm, enum stats_type st) +union signal_data Stats::getValue(enum Metric sm, enum Type st) const { - assert(s->state == STATE_INITIALIZED); - - const Hist &h = s->histograms[sm]; + const Hist &h = histograms.at(sm); union signal_data d; switch (st) { - case STATS_TYPE_TOTAL: + case Type::TOTAL: d.i = h.getTotal(); break; - case STATS_TYPE_LAST: + case Type::LAST: d.f = h.getLast(); break; - case STATS_TYPE_HIGHEST: + case Type::HIGHEST: d.f = h.getHighest(); break; - case STATS_TYPE_LOWEST: + case Type::LOWEST: d.f = h.getLowest(); break; - case STATS_TYPE_MEAN: + case Type::MEAN: d.f = h.getMean(); break; - case STATS_TYPE_STDDEV: + case Type::STDDEV: d.f = h.getStddev(); break; - case STATS_TYPE_VAR: + case Type::VAR: d.f = h.getVar(); break; @@ -284,3 +251,10 @@ union signal_data stats_get_value(const struct stats *s, enum stats_metric sm, e return d; } + +const Hist & Stats::getHistogram(enum Metric sm) const +{ + return histograms.at(sm); +} + +std::shared_ptr
Stats::table = std::shared_ptr
(); diff --git a/lib/super_node.cpp b/lib/super_node.cpp index 918ba2131..c9b55917c 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -382,7 +382,7 @@ void SuperNode::start() if (ret) throw RuntimeError("Failed to create timer"); - stats_print_header(STATS_FORMAT_HUMAN); + Stats::printHeader(Stats::Format::HUMAN); state = STATE_STARTED; } diff --git a/tests/unit/mapping.cpp b/tests/unit/mapping.cpp index c8b1a54db..ed6dd6c0d 100644 --- a/tests/unit/mapping.cpp +++ b/tests/unit/mapping.cpp @@ -28,6 +28,8 @@ #include #include +using namespace villas; + Test(mapping, parse_nodes) { int ret; @@ -73,8 +75,8 @@ Test(mapping, parse_nodes) cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "cherry")); cr_assert_eq(m.type, MAPPING_TYPE_STATS); - cr_assert_eq(m.stats.metric, STATS_METRIC_OWD); - cr_assert_eq(m.stats.type, STATS_TYPE_MEAN); + cr_assert_eq(m.stats.metric, Stats::Metric::OWD); + cr_assert_eq(m.stats.type, Stats::Type::MEAN); ret = mapping_parse_str(&m, "carrot.data[1-2]", &nodes); cr_assert_eq(ret, 0); @@ -126,8 +128,8 @@ Test(mapping, parse) ret = mapping_parse_str(&m, "stats.owd.mean", nullptr); cr_assert_eq(ret, 0); cr_assert_eq(m.type, MAPPING_TYPE_STATS); - cr_assert_eq(m.stats.metric, STATS_METRIC_OWD); - cr_assert_eq(m.stats.type, STATS_TYPE_MEAN); + cr_assert_eq(m.stats.metric, Stats::Metric::OWD); + cr_assert_eq(m.stats.type, Stats::Type::MEAN); ret = mapping_parse_str(&m, "data[1-2]", nullptr); cr_assert_eq(ret, 0); From ef17ec19a218e03364fd869f14409c3b3a254452 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 16:13:23 +0200 Subject: [PATCH 25/94] refactor enums to class enums --- common | 2 +- include/villas/api.hpp | 2 +- include/villas/api/server.hpp | 2 +- include/villas/hook.h | 48 ------- include/villas/hook.hpp | 68 ++++++---- include/villas/hooks/decimate.hpp | 2 +- include/villas/hooks/limit_rate.hpp | 2 +- include/villas/io.h | 24 ++-- include/villas/mapping.h | 28 ++-- include/villas/memory_type.h | 12 +- include/villas/node.h | 4 +- include/villas/node_direction.h | 12 +- include/villas/node_type.h | 6 +- include/villas/nodes/file.hpp | 4 +- include/villas/nodes/iec61850.hpp | 12 +- include/villas/nodes/loopback.hpp | 2 +- include/villas/nodes/rtp.hpp | 10 +- include/villas/nodes/signal_generator.hpp | 5 +- include/villas/nodes/socket.hpp | 2 +- include/villas/nodes/websocket.hpp | 4 +- include/villas/nodes/zeromq.hpp | 2 +- include/villas/path.h | 10 +- include/villas/plugin.h | 12 +- include/villas/pool.h | 2 +- include/villas/queue.h | 2 +- include/villas/queue_signalled.h | 24 ++-- include/villas/sample.h | 20 +-- include/villas/signal.h | 35 +++-- include/villas/socket_addr.h | 12 +- include/villas/stats.hpp | 2 +- include/villas/super_node.hpp | 6 +- include/villas/web.hpp | 4 +- lib/api.cpp | 12 +- lib/api/server.cpp | 14 +- lib/format_type.cpp | 2 +- lib/formats/csv.cpp | 48 +++---- lib/formats/json.cpp | 56 ++++---- lib/formats/json_reserve.cpp | 16 +-- lib/formats/msg.cpp | 10 +- lib/formats/protobuf.cpp | 54 ++++---- lib/formats/raw.cpp | 38 +++--- lib/formats/villas_binary.cpp | 20 +-- lib/formats/villas_human.cpp | 42 +++--- lib/hook.cpp | 14 +- lib/hook_list.cpp | 14 +- lib/hooks/average.cpp | 32 ++--- lib/hooks/cast.cpp | 28 ++-- lib/hooks/decimate.cpp | 18 +-- lib/hooks/dp.cpp | 28 ++-- lib/hooks/drop.cpp | 20 +-- lib/hooks/dump.cpp | 8 +- lib/hooks/ebm.cpp | 16 +-- lib/hooks/fix.cpp | 20 +-- lib/hooks/jitter_calc.cpp | 8 +- lib/hooks/limit_rate.cpp | 14 +- lib/hooks/print.cpp | 24 ++-- lib/hooks/restart.cpp | 18 +-- lib/hooks/scale.cpp | 24 ++-- lib/hooks/shift_seq.cpp | 12 +- lib/hooks/shift_ts.cpp | 14 +- lib/hooks/skip_first.cpp | 50 +++---- lib/hooks/stats.cpp | 46 +++---- lib/hooks/ts.cpp | 8 +- lib/io.cpp | 104 +++++++-------- lib/mapping.cpp | 50 +++---- lib/memory.cpp | 6 +- lib/memory/heap.cpp | 2 +- lib/memory/hugepage.cpp | 2 +- lib/node.cpp | 56 ++++---- lib/node_direction.cpp | 51 +++---- lib/node_type.cpp | 10 +- lib/nodes/amqp.cpp | 10 +- lib/nodes/comedi.cpp | 22 +-- lib/nodes/exec.cpp | 12 +- lib/nodes/file.cpp | 78 +++++------ lib/nodes/iec61850.cpp | 70 +++++----- lib/nodes/iec61850_sv.cpp | 64 ++++----- lib/nodes/infiniband.cpp | 32 ++--- lib/nodes/influxdb.cpp | 20 +-- lib/nodes/loopback.cpp | 24 ++-- lib/nodes/mqtt.cpp | 12 +- lib/nodes/nanomsg.cpp | 10 +- lib/nodes/ngsi.cpp | 8 +- lib/nodes/opal.cpp | 14 +- lib/nodes/rtp.cpp | 36 ++--- lib/nodes/shmem.cpp | 10 +- lib/nodes/signal_generator.cpp | 90 ++++++------- lib/nodes/socket.cpp | 56 ++++---- lib/nodes/stats.cpp | 12 +- lib/nodes/test_rtt.cpp | 18 +-- lib/nodes/uldaq.cpp | 12 +- lib/nodes/websocket.cpp | 56 ++++---- lib/nodes/zeromq.cpp | 32 ++--- lib/path.cpp | 61 ++++----- lib/path_source.cpp | 16 +-- lib/plugin.cpp | 6 +- lib/pool.cpp | 8 +- lib/queue.cpp | 16 +-- lib/queue_signalled.cpp | 96 ++++++------- lib/sample.cpp | 22 +-- lib/shmem.cpp | 15 +-- lib/signal.cpp | 156 +++++++++++----------- lib/socket_addr.cpp | 14 +- lib/stats.cpp | 14 +- lib/super_node.cpp | 40 +++--- lib/web.cpp | 10 +- plugins/example_hook.cpp | 2 +- src/villas-convert.cpp | 4 +- src/villas-hook.cpp | 24 ++-- src/villas-node.cpp | 6 +- src/villas-pipe.cpp | 12 +- src/villas-signal.cpp | 16 +-- src/villas-test-cmp.cpp | 12 +- tests/unit/io.cpp | 60 ++++----- tests/unit/mapping.cpp | 40 +++--- tests/unit/memory.cpp | 4 +- tests/unit/pool.cpp | 12 +- tests/unit/queue.cpp | 20 +-- tests/unit/queue_signalled.cpp | 21 +-- 119 files changed, 1381 insertions(+), 1415 deletions(-) delete mode 100644 include/villas/hook.h diff --git a/common b/common index 719ad763c..86993dec0 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 719ad763cce242e418b82b63bf596dfccb6c725b +Subproject commit 86993dec0a9aa7f83a7ade5f2cc79e2730b9c0df diff --git a/include/villas/api.hpp b/include/villas/api.hpp index 6ea9aac5f..8e7879928 100644 --- a/include/villas/api.hpp +++ b/include/villas/api.hpp @@ -54,7 +54,7 @@ class Api { protected: Logger logger; - enum state state; + enum State state; std::thread thread; std::atomic running; /**< Atomic flag for signalizing thread termination. */ diff --git a/include/villas/api/server.hpp b/include/villas/api/server.hpp index 85bd4afc8..537149978 100644 --- a/include/villas/api/server.hpp +++ b/include/villas/api/server.hpp @@ -51,7 +51,7 @@ class Socket; class Server { protected: - enum state state; + enum State state; Api *api; Logger logger; diff --git a/include/villas/hook.h b/include/villas/hook.h deleted file mode 100644 index b8d4021a8..000000000 --- a/include/villas/hook.h +++ /dev/null @@ -1,48 +0,0 @@ -/** Hook functions - * - * Every node or path can register hook functions which is called for every - * processed sample. This can be used to debug the data flow, get statistics - * or alter the sample contents. - * - * @file - * @author Steffen Vogel - * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASnode - * - * 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 - * 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 . - */ - -/** - * @addtogroup hooks User-defined hook functions - * @ingroup path - * @{ - *********************************************************************************/ - -#pragma once - -enum hook_flags { - HOOK_BUILTIN = (1 << 0), /**< Should we add this hook by default to every path?. */ - HOOK_PATH = (1 << 1), /**< This hook type is used by paths. */ - HOOK_NODE_READ = (1 << 2), /**< This hook type is used by nodes. */ - HOOK_NODE_WRITE = (1 << 3) /**< This hook type is used by nodes. */ -}; - -enum hook_reason { - HOOK_OK, - HOOK_ERROR, - HOOK_SKIP_SAMPLE, - HOOK_STOP_PROCESSING -}; diff --git a/include/villas/hook.hpp b/include/villas/hook.hpp index 073a63c09..79b0518fc 100644 --- a/include/villas/hook.hpp +++ b/include/villas/hook.hpp @@ -27,7 +27,6 @@ #pragma once -#include #include #include #include @@ -44,21 +43,36 @@ namespace node { class Hook { +public: + enum class Flags { + BUILTIN = (1 << 0), /**< Should we add this hook by default to every path?. */ + PATH = (1 << 1), /**< This hook type is used by paths. */ + NODE_READ = (1 << 2), /**< This hook type is used by nodes. */ + NODE_WRITE = (1 << 3) /**< This hook type is used by nodes. */ + }; + + enum class Reason { + OK, + ERROR, + SKIP_SAMPLE, + STOP_PROCESSING + }; + protected: Logger logger; - enum state state; + enum State state; int flags; - int priority; /**< A priority to change the order of execution within one type of hook. */ - int enabled; /**< Is this hook active? */ + int priority; /**< A priority to change the order of execution within one type of hook. */ + int enabled; /**< Is this hook active? */ struct path *path; struct node *node; vlist signals; - json_t *cfg; /**< A JSON object containing the configuration of the hook. */ + json_t *cfg; /**< A JSON object containing the configuration of the hook. */ public: Hook(struct path *p, struct node *n, int fl, int prio, bool en = true); @@ -81,42 +95,42 @@ public: /** Called whenever a hook is started; before threads are created. */ virtual void start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); - state = STATE_STARTED; + state = State::STARTED; } /** Called whenever a hook is stopped; after threads are destoyed. */ virtual void stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); - state = STATE_STOPPED; + state = State::STOPPED; } virtual void check() { - assert(state == STATE_PARSED); + assert(state == State::PARSED); - state = STATE_CHECKED; + state = State::CHECKED; } /** Called periodically. Period is set by global 'stats' option in the configuration file. */ virtual void periodic() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); } /** Called whenever a new simulation case is started. This is detected by a sequence no equal to zero. */ virtual void restart() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); } /** Called whenever a sample is processed. */ - virtual int process(sample *smp) + virtual Reason process(sample *smp) { - return HOOK_OK; + return Reason::OK; }; int getPriority() const @@ -129,7 +143,7 @@ public: return flags; } - struct vlist * getSignals() + struct vlist *getSignals() { return &signals; } @@ -149,9 +163,9 @@ public: void parse() { - assert(state == STATE_INITIALIZED); + assert(state == State::INITIALIZED); - state = STATE_PARSED; + state = State::PARSED; } void init() @@ -170,13 +184,12 @@ protected: int priority; public: - HookFactory(const std::string &name, const std::string &desc, int fl, int prio) : - Plugin(name, desc), - flags(fl), - priority(prio) + HookFactory(const std::string &name, const std::string &desc, int fl, int prio) : Plugin(name, desc), + flags(fl), + priority(prio) { } - virtual Hook * make(struct path *p, struct node *n) = 0; + virtual Hook *make(struct path *p, struct node *n) = 0; int getFlags() { @@ -184,16 +197,17 @@ public: } }; -template +template class HookPlugin : public HookFactory { public: using HookFactory::HookFactory; - virtual Hook * make(struct path *p, struct node *n) { + virtual Hook *make(struct path *p, struct node *n) + { return new T(p, n, flags, priority); }; }; -} // node -} // villas +} // namespace node +} // namespace villas diff --git a/include/villas/hooks/decimate.hpp b/include/villas/hooks/decimate.hpp index 72261bb44..555366999 100644 --- a/include/villas/hooks/decimate.hpp +++ b/include/villas/hooks/decimate.hpp @@ -60,7 +60,7 @@ public: virtual void parse(json_t *cfg); - virtual int process(sample *smp); + virtual Hook::Reason process(sample *smp); }; } /* namespace node */ diff --git a/include/villas/hooks/limit_rate.hpp b/include/villas/hooks/limit_rate.hpp index 26114b635..7f4547003 100644 --- a/include/villas/hooks/limit_rate.hpp +++ b/include/villas/hooks/limit_rate.hpp @@ -58,7 +58,7 @@ public: virtual void parse(json_t *cfg); - virtual int process(sample *smp); + virtual Hook::Reason process(sample *smp); }; diff --git a/include/villas/io.h b/include/villas/io.h index a74718368..42bf0f81c 100644 --- a/include/villas/io.h +++ b/include/villas/io.h @@ -32,23 +32,23 @@ struct sample; struct format_type; -enum io_flags { +enum class IOFlags { /* Bits 0-7 are reserved for for flags defined by enum sample_flags */ - IO_FLUSH = (1 << 8), /**< Flush the output stream after each chunk of samples. */ - IO_NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */ - IO_NEWLINES = (1 << 10), /**< The samples of this format are newline delimited. */ - IO_DESTROY_SIGNALS = (1 << 11), /**< Signal descriptors are managed by this IO instance. Destroy them in io_destoy() */ - IO_HAS_BINARY_PAYLOAD = (1 << 12) /**< This IO instance en/decodes binary payloads. */ + FLUSH = (1 << 8), /**< Flush the output stream after each chunk of samples. */ + NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */ + NEWLINES = (1 << 10), /**< The samples of this format are newline delimited. */ + DESTROY_SIGNALS = (1 << 11), /**< Signal descriptors are managed by this IO instance. Destroy them in io_destoy() */ + HAS_BINARY_PAYLOAD = (1 << 12) /**< This IO instance en/decodes binary payloads. */ }; -enum io_mode { - IO_MODE_STDIO, - IO_MODE_ADVIO, - IO_MODE_CUSTOM +enum class IOMode { + STDIO, + ADVIO, + CUSTOM }; struct io { - enum state state; + enum State state; int flags; char delimiter; /**< Newline delimiter. */ char separator; /**< Column separator (used by csv and villas.human formats only) */ @@ -70,7 +70,7 @@ struct io { struct vlist *signals; /**< Signal meta data for parsed samples by io_scan() */ bool header_printed; - enum io_mode mode; + enum IOMode mode; void *_vd; const struct format_type *_vt; diff --git a/include/villas/mapping.h b/include/villas/mapping.h index 6859109de..650bc6284 100644 --- a/include/villas/mapping.h +++ b/include/villas/mapping.h @@ -34,27 +34,27 @@ struct sample; struct signal; struct vlist; -enum mapping_type { - MAPPING_TYPE_DATA, - MAPPING_TYPE_STATS, - MAPPING_TYPE_HEADER, - MAPPING_TYPE_TIMESTAMP +enum class MappingType { + DATA, + STATS, + HEADER, + TIMESTAMP }; -enum mapping_header_type { - MAPPING_HEADER_TYPE_LENGTH, - MAPPING_HEADER_TYPE_SEQUENCE +enum class MappingHeaderType { + LENGTH, + SEQUENCE }; -enum mapping_timestamp_type { - MAPPING_TIMESTAMP_TYPE_ORIGIN, - MAPPING_TIMESTAMP_TYPE_RECEIVED +enum class MappingTimestampType { + ORIGIN, + RECEIVED }; struct mapping_entry { struct node *node; /**< The node to which this mapping refers. */ - enum mapping_type type; /**< The mapping type. Selects one of the union fields below. */ + enum MappingType type; /**< The mapping type. Selects one of the union fields below. */ /** The number of values which is covered by this mapping entry. * @@ -75,11 +75,11 @@ struct mapping_entry { } stats; struct { - enum mapping_header_type type; + enum MappingHeaderType type; } header; struct { - enum mapping_timestamp_type type; + enum MappingTimestampType type; } timestamp; }; }; diff --git a/include/villas/memory_type.h b/include/villas/memory_type.h index b0823642b..d8802d364 100644 --- a/include/villas/memory_type.h +++ b/include/villas/memory_type.h @@ -33,11 +33,11 @@ struct node; typedef struct memory_allocation * (*memory_allocator_t)(struct memory_type *mem, size_t len, size_t alignment); typedef int (*memory_deallocator_t)(struct memory_type *mem, struct memory_allocation * ma); -enum memory_type_flags { - MEMORY_MMAP = (1 << 0), - MEMORY_DMA = (1 << 1), - MEMORY_HUGEPAGE = (1 << 2), - MEMORY_HEAP = (1 << 3) +enum class MemoryFlags { + MMAP = (1 << 0), + DMA = (1 << 1), + HUGEPAGE = (1 << 2), + HEAP = (1 << 3) }; struct memory_type { @@ -60,5 +60,5 @@ struct memory_type * memory_managed(void *ptr, size_t len); int memory_hugepage_init(int hugepages); -struct memory_type * memory_type_lookup(enum memory_type_flags flags); +struct memory_type * memory_type_lookup(enum MemoryFlags flags); diff --git a/include/villas/node.h b/include/villas/node.h index 955986912..d1ae987d6 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -59,7 +59,7 @@ struct node { char *name; /**< A short identifier of the node, only used for configuration and logging */ int enabled; - enum state state; + enum State state; char *_name; /**< Singleton: A string used to print to screen. */ char *_name_long; /**< Singleton: A string used to print to screen. */ @@ -199,6 +199,6 @@ bool node_is_valid_name(const char *name); bool node_is_enabled(const struct node *n); -struct vlist * node_get_signals(struct node *n, enum node_dir dir); +struct vlist * node_get_signals(struct node *n, enum NodeDir dir); /** @} */ diff --git a/include/villas/node_direction.h b/include/villas/node_direction.h index ed07b4cf8..15624eaab 100644 --- a/include/villas/node_direction.h +++ b/include/villas/node_direction.h @@ -36,14 +36,14 @@ /* Forward declarations */ struct node; -enum node_dir { - NODE_DIR_IN, /**< VILLASnode is receiving/reading */ - NODE_DIR_OUT /**< VILLASnode is sending/writing */ +enum class NodeDir { + IN, /**< VILLASnode is receiving/reading */ + OUT /**< VILLASnode is sending/writing */ }; struct node_direction { - enum state state; - enum node_dir direction; + enum State state; + enum NodeDir direction; int enabled; int builtin; /**< This node should use built-in hooks by default. */ @@ -55,7 +55,7 @@ struct node_direction { json_t *cfg; /**< A JSON object containing the configuration of the node. */ }; -int node_direction_init(struct node_direction *nd, enum node_dir dir, struct node *n); +int node_direction_init(struct node_direction *nd, enum NodeDir dir, struct node *n); int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg); diff --git a/include/villas/node_type.h b/include/villas/node_type.h index eabd76865..c2bab7ce1 100644 --- a/include/villas/node_type.h +++ b/include/villas/node_type.h @@ -37,8 +37,8 @@ struct node; struct sample; -enum node_type_flags { - NODE_TYPE_PROVIDES_SIGNALS = (1 << 0) +enum class NodeFlags { + PROVIDES_SIGNALS = (1 << 0) }; /** C++ like vtable construct for node_types */ @@ -46,7 +46,7 @@ struct node_type { unsigned vectorize; /**< Maximal vector length supported by this node type. Zero is unlimited. */ int flags; - enum state state; /**< State of this node-type. */ + enum State state; /**< State of this node-type. */ struct vlist instances; /**< A list of all existing nodes of this type. */ diff --git a/include/villas/nodes/file.hpp b/include/villas/nodes/file.hpp index 3e80798c5..409c627fd 100644 --- a/include/villas/nodes/file.hpp +++ b/include/villas/nodes/file.hpp @@ -49,7 +49,7 @@ struct file { size_t buffer_size_out; /**< Defines size of output stream buffer. No buffer is created if value is set to zero. */ size_t buffer_size_in; /**< Defines size of input stream buffer. No buffer is created if value is set to zero. */ - enum epoch { + enum class EpochMode { DIRECT, WAIT, RELATIVE, @@ -57,7 +57,7 @@ struct file { ORIGINAL } epoch_mode; /**< Specifies how file::offset is calculated. */ - enum eof { + enum class EOFBehaviour { STOP, /**< Terminate when EOF is reached. */ REWIND, /**< Rewind the file when EOF is reached. */ SUSPEND /**< Blocking wait when EOF is reached. */ diff --git a/include/villas/nodes/iec61850.hpp b/include/villas/nodes/iec61850.hpp index c029ad377..d021411af 100644 --- a/include/villas/nodes/iec61850.hpp +++ b/include/villas/nodes/iec61850.hpp @@ -45,7 +45,7 @@ #include #include -enum iec61850_type { +enum class IEC61850Type { /* According to IEC 61850-7-2 */ BOOLEAN, INT8, @@ -73,8 +73,8 @@ enum iec61850_type { struct iec61850_type_descriptor { const char *name; - enum iec61850_type iec_type; - enum signal_type type; + enum IEC61850Type iec_type; + enum SignalType type; unsigned size; bool publisher; bool subscriber; @@ -85,7 +85,7 @@ struct iec61850_receiver { EthernetSocket socket; - enum type { + enum class Type { GOOSE, SAMPLED_VALUES } type; @@ -106,9 +106,9 @@ const struct iec61850_type_descriptor * iec61850_lookup_type(const char *name); int iec61850_parse_signals(json_t *json_signals, struct vlist *signals, struct vlist *node_signals); -struct iec61850_receiver * iec61850_receiver_lookup(enum iec61850_receiver::type t, const char *intf); +struct iec61850_receiver * iec61850_receiver_lookup(enum iec61850_receiver::Type t, const char *intf); -struct iec61850_receiver * iec61850_receiver_create(enum iec61850_receiver::type t, const char *intf); +struct iec61850_receiver * iec61850_receiver_create(enum iec61850_receiver::Type t, const char *intf); int iec61850_receiver_start(struct iec61850_receiver *r); diff --git a/include/villas/nodes/loopback.hpp b/include/villas/nodes/loopback.hpp index abed0a331..c88a05953 100644 --- a/include/villas/nodes/loopback.hpp +++ b/include/villas/nodes/loopback.hpp @@ -41,7 +41,7 @@ struct sample; */ struct loopback { int queuelen; - int queueflags; + enum QueueSignalledMode mode; struct queue_signalled queue; struct pool pool; }; diff --git a/include/villas/nodes/rtp.hpp b/include/villas/nodes/rtp.hpp index 00227e73b..cf130bdb4 100644 --- a/include/villas/nodes/rtp.hpp +++ b/include/villas/nodes/rtp.hpp @@ -55,10 +55,10 @@ struct format_type; #define RTP_INITIAL_BUFFER_LEN 1500 #define RTP_PACKET_TYPE 21 -enum rtp_hook_type { - RTCP_HOOK_DISABLED, - RTCP_HOOK_DECIMATE, - RTCP_HOOK_LIMIT_RATE +enum class RTPHookType { + DISABLED, + DECIMATE, + LIMIT_RATE }; struct rtp { @@ -84,7 +84,7 @@ struct rtp { double a; double b; - enum rtp_hook_type rate_hook_type; + enum RTPHookType rate_hook_type; villas::node::LimitHook *rate_hook; villas::dsp::PID rate_pid; diff --git a/include/villas/nodes/signal_generator.hpp b/include/villas/nodes/signal_generator.hpp index 0ccfa144b..857901861 100644 --- a/include/villas/nodes/signal_generator.hpp +++ b/include/villas/nodes/signal_generator.hpp @@ -43,7 +43,7 @@ struct signal_generator { struct task task; /**< Timer for periodic events. */ int rt; /**< Real-time mode? */ - enum type { + enum class SignalType { RANDOM, SINE, SQUARE, @@ -51,8 +51,7 @@ struct signal_generator { RAMP, COUNTER, CONSTANT, - MIXED, - INVALID + MIXED } type; /**< Signal type */ double rate; /**< Sampling rate. */ diff --git a/include/villas/nodes/socket.hpp b/include/villas/nodes/socket.hpp index b72d93cc0..0ffb0776a 100644 --- a/include/villas/nodes/socket.hpp +++ b/include/villas/nodes/socket.hpp @@ -44,7 +44,7 @@ struct socket { int sd; /**< The socket descriptor */ int verify_source; /**< Verify the source address of incoming packets against socket::remote. */ - enum socket_layer layer; /**< The OSI / IP layer which should be used for this socket */ + enum SocketLayer layer; /**< The OSI / IP layer which should be used for this socket */ struct format_type *format; struct io io; diff --git a/include/villas/nodes/websocket.hpp b/include/villas/nodes/websocket.hpp index 35eae229f..3d01407ff 100644 --- a/include/villas/nodes/websocket.hpp +++ b/include/villas/nodes/websocket.hpp @@ -53,7 +53,7 @@ struct websocket { /* Internal datastructures */ struct websocket_connection { - enum state { + enum State { DESTROYED, INITIALIZED, CONNECTING, @@ -63,7 +63,7 @@ struct websocket_connection { ERROR } state; /**< The current status of this connection. */ - enum mode { + enum class Mode { CLIENT, SERVER, } mode; diff --git a/include/villas/nodes/zeromq.hpp b/include/villas/nodes/zeromq.hpp index 0178225ca..b1f2fe31d 100644 --- a/include/villas/nodes/zeromq.hpp +++ b/include/villas/nodes/zeromq.hpp @@ -59,7 +59,7 @@ struct zeromq { } server, client; } curve; - enum pattern { + enum class Pattern { PUBSUB, #ifdef ZMQ_BUILD_DISH RADIODISH diff --git a/include/villas/path.h b/include/villas/path.h index 50eabcf50..1a6f882bc 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -48,16 +48,16 @@ struct stats; struct node; /** The register mode determines under which condition the path is triggered. */ -enum path_mode { - PATH_MODE_ANY, /**< The path is triggered whenever one of the sources receives samples. */ - PATH_MODE_ALL /**< The path is triggered only after all sources have received at least 1 sample. */ +enum class PathMode { + ANY, /**< The path is triggered whenever one of the sources receives samples. */ + ALL /**< The path is triggered only after all sources have received at least 1 sample. */ }; /** The datastructure for a path. */ struct path { - enum state state; /**< Path state. */ + enum State state; /**< Path state. */ - enum path_mode mode; /**< Determines when this path is triggered. */ + enum PathMode mode; /**< Determines when this path is triggered. */ struct { int nfds; diff --git a/include/villas/plugin.h b/include/villas/plugin.h index 3db4c954e..f1e08f2e0 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -30,16 +30,16 @@ extern struct vlist plugins; -enum plugin_type { - PLUGIN_TYPE_NODE, - PLUGIN_TYPE_FORMAT, +enum PluginType { + NODE, + FORMAT, }; struct plugin { const char *name; const char *description; - enum plugin_type type; + enum PluginType type; union { struct format_type format; @@ -53,7 +53,7 @@ struct plugin { #define plugin_name(vt) plugin(vt)->name #define plugin_description(vt) plugin(vt)->description -void plugin_dump(enum plugin_type type); +void plugin_dump(enum PluginType type); /** Find registered and loaded plugin with given name and type. */ -struct plugin * plugin_lookup(enum plugin_type type, const char *name); +struct plugin * plugin_lookup(enum PluginType type, const char *name); diff --git a/include/villas/pool.h b/include/villas/pool.h index 310ba8ebc..027787c2e 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -34,7 +34,7 @@ /** A thread-safe memory pool */ struct pool { - enum state state; + enum State state; off_t buffer_off; /**< Offset from the struct address to the underlying memory area */ diff --git a/include/villas/queue.h b/include/villas/queue.h index 393370c12..5836b2282 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -54,7 +54,7 @@ struct queue_cell { /** A lock-free multiple-producer, multiple-consumer (MPMC) queue. */ struct queue { - std::atomic state; + std::atomic state; cacheline_pad_t _pad0; /**< Shared area: all threads read */ diff --git a/include/villas/queue_signalled.h b/include/villas/queue_signalled.h index 744f46daf..916052cd1 100644 --- a/include/villas/queue_signalled.h +++ b/include/villas/queue_signalled.h @@ -27,27 +27,27 @@ #include -enum queue_signalled_flags { - /* Mode */ - QUEUE_SIGNALLED_AUTO = (0 << 0), /**< We will choose the best method available on the platform */ - QUEUE_SIGNALLED_PTHREAD = (1 << 0), - QUEUE_SIGNALLED_POLLING = (2 << 0), +enum class QueueSignalledMode { + AUTO, /**< We will choose the best method available on the platform */ + PTHREAD, + POLLING, #ifdef HAS_EVENTFD - QUEUE_SIGNALLED_EVENTFD = (3 << 0), + EVENTFD, #elif defined(__APPLE__) - QUEUE_SIGNALLED_PIPE = (3 << 0), + PIPE, #endif - QUEUE_SIGNALLED_MASK = 0xf, +}; - /* Other flags */ - QUEUE_SIGNALLED_PROCESS_SHARED = (1 << 4) +enum class QueueSignalledFlags { + PROCESS_SHARED = (1 << 4) }; /** Wrapper around queue that uses POSIX CV's for signalling writes. */ struct queue_signalled { struct queue queue; /**< Actual underlying queue. */ - enum queue_signalled_flags mode; + enum QueueSignalledMode mode; + enum QueueSignalledFlags flags; union { struct { @@ -64,7 +64,7 @@ struct queue_signalled { #define queue_signalled_available(q) queue_available(&((q)->queue)) -int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_type *mem, int flags); +int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_type *mem, enum QueueSignalledMode mode = QueueSignalledMode::AUTO, int flags = 0); int queue_signalled_destroy(struct queue_signalled *qs); diff --git a/include/villas/sample.h b/include/villas/sample.h index b8b3d50ec..bc2aa0480 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -48,16 +48,16 @@ struct pool; #define SAMPLE_DATA_OFFSET(smp) ((char *) (smp) + offsetof(struct sample, data)) /** Parts of a sample that can be serialized / de-serialized by the IO formats */ -enum sample_flags { - SAMPLE_HAS_TS_ORIGIN = (1 << 0), /**< Include origin timestamp in output. */ - SAMPLE_HAS_TS_RECEIVED = (1 << 1), /**< Include receive timestamp in output. */ - SAMPLE_HAS_OFFSET = (1 << 2), /**< Include offset (received - origin timestamp) in output. */ - SAMPLE_HAS_SEQUENCE = (1 << 3), /**< Include sequence number in output. */ - SAMPLE_HAS_DATA = (1 << 4), /**< Include values in output. */ - SAMPLE_HAS_ALL = (1 << 5) - 1, /**< Enable all output options. */ +enum class SampleFlags { + HAS_TS_ORIGIN = (1 << 0), /**< Include origin timestamp in output. */ + HAS_TS_RECEIVED = (1 << 1), /**< Include receive timestamp in output. */ + HAS_OFFSET = (1 << 2), /**< Include offset (received - origin timestamp) in output. */ + HAS_SEQUENCE = (1 << 3), /**< Include sequence number in output. */ + HAS_DATA = (1 << 4), /**< Include values in output. */ + HAS_ALL = (1 << 5) - 1, /**< Enable all output options. */ - SAMPLE_IS_FIRST = (1 << 16), /**< This sample is the first of a new simulation case */ - SAMPLE_IS_LAST = (1 << 17) /**< This sample is the last of a running simulation case */ + IS_FIRST = (1 << 16), /**< This sample is the first of a new simulation case */ + IS_LAST = (1 << 17) /**< This sample is the last of a running simulation case */ }; struct sample { @@ -130,7 +130,7 @@ int sample_copy_many(struct sample *dsts[], struct sample *srcs[], int cnt); int sample_incref_many(struct sample *smps[], int cnt); int sample_decref_many(struct sample *smps[], int cnt); -enum signal_type sample_format(const struct sample *s, unsigned idx); +enum SignalType sample_format(const struct sample *s, unsigned idx); void sample_data_insert(struct sample *smp, const union signal_data *src, size_t offset, size_t len); diff --git a/include/villas/signal.h b/include/villas/signal.h index 352bbda6c..f73f22831 100644 --- a/include/villas/signal.h +++ b/include/villas/signal.h @@ -43,18 +43,18 @@ struct mapping_entry; * Data is in host endianess! */ union signal_data { - double f; /**< Floating point values. */ - int64_t i; /**< Integer values. */ - bool b; /**< Boolean values. */ - float _Complex z; /**< Complex values. */ + double f; /**< Floating point values. */ + int64_t i; /**< Integer values. */ + bool b; /**< Boolean values. */ + float _Complex z; /**< Complex values. */ }; -enum signal_type { - SIGNAL_TYPE_INVALID = 0, /**< Signal type is invalid. */ - SIGNAL_TYPE_FLOAT = 1, /**< See signal_data::f */ - SIGNAL_TYPE_INTEGER = 2, /**< See signal_data::i */ - SIGNAL_TYPE_BOOLEAN = 3, /**< See signal_data::b */ - SIGNAL_TYPE_COMPLEX = 4 /**< See signal_data::z */ +enum class SignalType { + INVALID = 0, /**< Signal type is invalid. */ + FLOAT = 1, /**< See signal_data::f */ + INTEGER = 2, /**< See signal_data::i */ + BOOLEAN = 3, /**< See signal_data::b */ + COMPLEX = 4 /**< See signal_data::z */ }; /** Signal descriptor. @@ -71,7 +71,7 @@ struct signal { std::atomic refcnt; /**< Reference counter. */ - enum signal_type type; + enum SignalType type; }; /** Initialize a signal with default values. */ @@ -81,7 +81,7 @@ int signal_init(struct signal *s); int signal_destroy(struct signal *s); /** Allocate memory for a new signal, and initialize it with provided values. */ -struct signal * signal_create(const char *name, const char *unit, enum signal_type fmt); +struct signal * signal_create(const char *name, const char *unit, enum SignalType fmt); /** Destroy and release memory of signal. */ int signal_free(struct signal *s); @@ -104,18 +104,18 @@ int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, u int signal_list_init(struct vlist *list); int signal_list_destroy(struct vlist *list); int signal_list_parse(struct vlist *list, json_t *cfg); -int signal_list_generate(struct vlist *list, unsigned len, enum signal_type fmt); +int signal_list_generate(struct vlist *list, unsigned len, enum SignalType fmt); int signal_list_generate2(struct vlist *list, const char *dt); void signal_list_dump(const struct vlist *list, const union signal_data *data, unsigned len); int signal_list_copy(struct vlist *dst, const struct vlist *src); -enum signal_type signal_type_from_str(const char *str); +enum SignalType signal_type_from_str(const char *str); -enum signal_type signal_type_from_fmtstr(char c); +enum SignalType signal_type_from_fmtstr(char c); -const char * signal_type_to_str(enum signal_type fmt); +const char * signal_type_to_str(enum SignalType fmt); -enum signal_type signal_type_detect(const char *val); +enum SignalType signal_type_detect(const char *val); /** Convert signal data from one description/format to another. */ void signal_data_cast(union signal_data *data, const struct signal *from, const struct signal *to); @@ -128,4 +128,3 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con int signal_data_parse_json(union signal_data *data, const struct signal *sig, json_t *cfg); void signal_data_set(union signal_data *data, const struct signal *sig, double val); - diff --git a/include/villas/socket_addr.h b/include/villas/socket_addr.h index 9e2bf3ef0..19c4e6635 100644 --- a/include/villas/socket_addr.h +++ b/include/villas/socket_addr.h @@ -37,11 +37,11 @@ #include #endif /* LIBNL3_ROUTE_FOUND */ -enum socket_layer { - SOCKET_LAYER_ETH, - SOCKET_LAYER_IP, - SOCKET_LAYER_UDP, - SOCKET_LAYER_UNIX +enum class SocketLayer { + ETH, + IP, + UDP, + UNIX }; union sockaddr_union { @@ -79,6 +79,6 @@ char * socket_print_addr(struct sockaddr *saddr); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int socket_parse_address(const char *str, struct sockaddr *sa, enum socket_layer layer, int flags); +int socket_parse_address(const char *str, struct sockaddr *sa, enum SocketLayer layer, int flags); int socket_compare_addr(struct sockaddr *x, struct sockaddr *y); diff --git a/include/villas/stats.hpp b/include/villas/stats.hpp index 65128b63f..7736e2cd0 100644 --- a/include/villas/stats.hpp +++ b/include/villas/stats.hpp @@ -87,7 +87,7 @@ protected: struct TypeDescription { const char *name; - enum signal_type signal_type; + enum SignalType signal_type; }; static std::shared_ptr
table; diff --git a/include/villas/super_node.hpp b/include/villas/super_node.hpp index d72d2d940..2238913cd 100644 --- a/include/villas/super_node.hpp +++ b/include/villas/super_node.hpp @@ -42,7 +42,7 @@ namespace node { class SuperNode { protected: - enum state state; + enum State state; int idleStop; @@ -111,7 +111,7 @@ public: /** Run periodic hooks of this super node. */ int periodic(); - void setState(enum state st) + void setState(enum State st) { state = st; } @@ -134,7 +134,7 @@ public: return &interfaces; } - enum state getState() { + enum State getState() { return state; } diff --git a/include/villas/web.hpp b/include/villas/web.hpp index 3b16587f0..3f1ff64f2 100644 --- a/include/villas/web.hpp +++ b/include/villas/web.hpp @@ -41,7 +41,7 @@ class Api; class Web { protected: - enum state state; + enum State state; Logger logger; @@ -93,7 +93,7 @@ public: return vhost; } - enum state getState() const + enum State getState() const { return state; } diff --git a/lib/api.cpp b/lib/api.cpp index 817299ff4..87cde2ca0 100644 --- a/lib/api.cpp +++ b/lib/api.cpp @@ -33,7 +33,7 @@ using namespace villas::node; using namespace villas::node::api; Api::Api(SuperNode *sn) : - state(STATE_INITIALIZED), + state(State::INITIALIZED), super_node(sn), server(this) { @@ -42,12 +42,12 @@ Api::Api(SuperNode *sn) : Api::~Api() { - assert(state != STATE_STARTED); + assert(state != State::STARTED); } void Api::start() { - assert(state != STATE_STARTED); + assert(state != State::STARTED); logger->info("Starting sub-system"); @@ -56,12 +56,12 @@ void Api::start() running = true; thread = std::thread(&Api::worker, this); - state = STATE_STARTED; + state = State::STARTED; } void Api::stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); logger->info("Stopping sub-system"); @@ -79,7 +79,7 @@ void Api::stop() server.stop(); - state = STATE_STOPPED; + state = State::STOPPED; } void Api::run() diff --git a/lib/api/server.cpp b/lib/api/server.cpp index 575f1fe92..5d4e3461f 100644 --- a/lib/api/server.cpp +++ b/lib/api/server.cpp @@ -50,7 +50,7 @@ using namespace villas::node::api; #endif Server::Server(Api *a) : - state(STATE_INITIALIZED), + state(State::INITIALIZED), api(a) { logger = logging.get("api:server"); @@ -58,14 +58,14 @@ Server::Server(Api *a) : Server::~Server() { - assert(state != STATE_STARTED); + assert(state != State::STARTED); } void Server::start() { int ret; - assert(state != STATE_STARTED); + assert(state != State::STARTED); sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd < 0) @@ -90,7 +90,7 @@ void Server::start() logger->info("Listening on UNIX socket: {}", sun.sun_path); - state = STATE_STARTED; + state = State::STARTED; } struct sockaddr_un Server::getSocketAddress() @@ -129,20 +129,20 @@ void Server::stop() { int ret; - assert(state == STATE_STARTED); + assert(state == State::STARTED); ret = close(sd); if (ret) throw SystemError("Failed to close API socket");; - state = STATE_STOPPED; + state = State::STOPPED; } void Server::run(int timeout) { int ret; - assert(state == STATE_STARTED); + assert(state == State::STARTED); auto len = pfds.size(); diff --git a/lib/format_type.cpp b/lib/format_type.cpp index 0b5e93e66..bf5b84c06 100644 --- a/lib/format_type.cpp +++ b/lib/format_type.cpp @@ -30,7 +30,7 @@ struct format_type * format_type_lookup(const char *name) { struct plugin *p; - p = plugin_lookup(PLUGIN_TYPE_FORMAT, name); + p = plugin_lookup(PluginType::FORMAT, name); if (!p) return nullptr; diff --git a/lib/formats/csv.cpp b/lib/formats/csv.cpp index 481c0edc6..26ae90be2 100644 --- a/lib/formats/csv.cpp +++ b/lib/formats/csv.cpp @@ -38,28 +38,28 @@ static size_t csv_sprint_single(struct io *io, char *buf, size_t len, const stru size_t off = 0; struct signal *sig; - if (io->flags & SAMPLE_HAS_TS_ORIGIN) { - if (io->flags & SAMPLE_HAS_TS_ORIGIN) + if (io->flags & (int) SampleFlags::HAS_TS_ORIGIN) { + if (io->flags & (int) SampleFlags::HAS_TS_ORIGIN) off += snprintf(buf + off, len - off, "%ld%c%09ld", smp->ts.origin.tv_sec, io->separator, smp->ts.origin.tv_nsec); else off += snprintf(buf + off, len - off, "nan%cnan", io->separator); } - if (io->flags & SAMPLE_HAS_OFFSET) { - if ((smp->flags & SAMPLE_HAS_TS_RECEIVED) && (smp->flags & SAMPLE_HAS_TS_RECEIVED)) + if (io->flags & (int) SampleFlags::HAS_OFFSET) { + if ((smp->flags & (int) SampleFlags::HAS_TS_RECEIVED) && (smp->flags & (int) SampleFlags::HAS_TS_RECEIVED)) off += snprintf(buf + off, len - off, "%c%.09f", io->separator, time_delta(&smp->ts.origin, &smp->ts.received)); else off += snprintf(buf + off, len - off, "%cnan", io->separator); } - if (io->flags & SAMPLE_HAS_SEQUENCE) { - if (smp->flags & SAMPLE_HAS_SEQUENCE) + if (io->flags & (int) SampleFlags::HAS_SEQUENCE) { + if (smp->flags & (int) SampleFlags::HAS_SEQUENCE) off += snprintf(buf + off, len - off, "%c%" PRIu64, io->separator, smp->sequence); else off += snprintf(buf + off, len - off, "%cnan", io->separator); } - if (io->flags & SAMPLE_HAS_DATA) { + if (io->flags & (int) SampleFlags::HAS_DATA) { for (unsigned i = 0; i < smp->length; i++) { sig = (struct signal *) vlist_at_safe(smp->signals, i); if (!sig) @@ -99,7 +99,7 @@ static size_t csv_sscan_single(struct io *io, const char *buf, size_t len, struc ptr = end + 1; - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; offset = strtof(ptr, &end); if (end == ptr || *end == io->delimiter) @@ -111,7 +111,7 @@ static size_t csv_sscan_single(struct io *io, const char *buf, size_t len, struc if (end == ptr || *end == io->delimiter) goto out; - smp->flags |= SAMPLE_HAS_SEQUENCE; + smp->flags |= (int) SampleFlags::HAS_SEQUENCE; for (ptr = end + 1, i = 0; i < smp->capacity; ptr = end + 1, i++) { @@ -132,7 +132,7 @@ out: if (*end == io->delimiter) smp->length = i; if (smp->length > 0) - smp->flags |= SAMPLE_HAS_DATA; + smp->flags |= (int) SampleFlags::HAS_DATA; return end - buf; } @@ -170,16 +170,16 @@ void csv_header(struct io *io, const struct sample *smp) FILE *f = io_stream_output(io); fprintf(f, "# "); - if (io->flags & SAMPLE_HAS_TS_ORIGIN) + if (io->flags & (int) SampleFlags::HAS_TS_ORIGIN) fprintf(f, "secs%cnsecs%c", io->separator, io->separator); - if (io->flags & SAMPLE_HAS_OFFSET) + if (io->flags & (int) SampleFlags::HAS_OFFSET) fprintf(f, "offset%c", io->separator); - if (io->flags & SAMPLE_HAS_SEQUENCE) + if (io->flags & (int) SampleFlags::HAS_SEQUENCE) fprintf(f, "sequence%c", io->separator); - if (io->flags & SAMPLE_HAS_DATA) { + if (io->flags & (int) SampleFlags::HAS_DATA) { for (unsigned i = 0; i < smp->length; i++) { struct signal *sig = (struct signal *) vlist_at(smp->signals, i); @@ -201,48 +201,48 @@ void csv_header(struct io *io, const struct sample *smp) static struct plugin p1; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p1.name = "tsv"; p1.description = "Tabulator-separated values"; - p1.type = PLUGIN_TYPE_FORMAT; + p1.type = PluginType::FORMAT; p1.format.header = csv_header; p1.format.sprint = csv_sprint; p1.format.sscan = csv_sscan; p1.format.size = 0; - p1.format.flags = IO_NEWLINES | - SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p1.format.flags = (int) IOFlags::NEWLINES | + (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; p1.format.separator = '\t'; vlist_push(&plugins, &p1); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p1); } static struct plugin p2; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p2.name = "csv"; p2.description = "Comma-separated values"; - p2.type = PLUGIN_TYPE_FORMAT; + p2.type = PluginType::FORMAT; p2.format.header = csv_header; p2.format.sprint = csv_sprint; p2.format.sscan = csv_sscan; p2.format.size = 0; - p2.format.flags = IO_NEWLINES | - SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p2.format.flags = (int) IOFlags::NEWLINES | + (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; p2.format.separator = ','; vlist_push(&plugins, &p2); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p2); } diff --git a/lib/formats/json.cpp b/lib/formats/json.cpp index ca461a891..d2a33e326 100644 --- a/lib/formats/json.cpp +++ b/lib/formats/json.cpp @@ -27,26 +27,26 @@ #include #include -static enum signal_type json_detect_format(json_t *val) +static enum SignalType json_detect_format(json_t *val) { int type = json_typeof(val); switch (type) { case JSON_REAL: - return SIGNAL_TYPE_FLOAT; + return SignalType::FLOAT; case JSON_INTEGER: - return SIGNAL_TYPE_INTEGER; + return SignalType::INTEGER; case JSON_TRUE: case JSON_FALSE: - return SIGNAL_TYPE_BOOLEAN; + return SignalType::BOOLEAN; case JSON_OBJECT: - return SIGNAL_TYPE_COMPLEX; /* must be a complex number */ + return SignalType::COMPLEX; /* must be a complex number */ default: - return SIGNAL_TYPE_INVALID; + return SignalType::INVALID; } } @@ -60,13 +60,13 @@ static json_t * json_pack_timestamps(struct io *io, struct sample *smp) const char *fmt = "[ I, I ]"; #endif - if (io->flags & SAMPLE_HAS_TS_ORIGIN) { - if (smp->flags & SAMPLE_HAS_TS_ORIGIN) + if (io->flags & (int) SampleFlags::HAS_TS_ORIGIN) { + if (smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) json_object_set(json_ts, "origin", json_pack(fmt, smp->ts.origin.tv_sec, smp->ts.origin.tv_nsec)); } - if (io->flags & SAMPLE_HAS_TS_RECEIVED) { - if (smp->flags & SAMPLE_HAS_TS_RECEIVED) + if (io->flags & (int) SampleFlags::HAS_TS_RECEIVED) { + if (smp->flags & (int) SampleFlags::HAS_TS_RECEIVED) json_object_set(json_ts, "received", json_pack(fmt, smp->ts.received.tv_sec, smp->ts.received.tv_nsec)); } @@ -90,7 +90,7 @@ static int json_unpack_timestamps(json_t *json_ts, struct sample *smp) if (ret) return ret; - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; } if (json_ts_received) { @@ -98,7 +98,7 @@ static int json_unpack_timestamps(json_t *json_ts, struct sample *smp) if (ret) return ret; - smp->flags |= SAMPLE_HAS_TS_RECEIVED; + smp->flags |= (int) SampleFlags::HAS_TS_RECEIVED; } return 0; @@ -111,42 +111,42 @@ static int json_pack_sample(struct io *io, json_t **j, struct sample *smp) json_smp = json_pack_ex(&err, 0, "{ s: o }", "ts", json_pack_timestamps(io, smp)); - if (io->flags & SAMPLE_HAS_SEQUENCE) { - if (smp->flags & SAMPLE_HAS_SEQUENCE) { + if (io->flags & (int) SampleFlags::HAS_SEQUENCE) { + if (smp->flags & (int) SampleFlags::HAS_SEQUENCE) { json_t *json_sequence = json_integer(smp->sequence); json_object_set(json_smp, "sequence", json_sequence); } } - if (io->flags & SAMPLE_HAS_DATA) { + if (io->flags & (int) SampleFlags::HAS_DATA) { json_t *json_data = json_array(); for (unsigned i = 0; i < smp->length; i++) { - enum signal_type fmt = sample_format(smp, i); + enum SignalType fmt = sample_format(smp, i); json_t *json_value; switch (fmt) { - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: json_value = json_integer(smp->data[i].i); break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: json_value = json_real(smp->data[i].f); break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: json_value = json_boolean(smp->data[i].b); break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: json_value = json_pack("{ s: f, s: f }", "real", creal(smp->data[i].z), "imag", cimag(smp->data[i].z) ); break; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: return -1; } @@ -212,7 +212,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm if (sequence >= 0) { smp->sequence = sequence; - smp->flags |= SAMPLE_HAS_SEQUENCE; + smp->flags |= (int) SampleFlags::HAS_SEQUENCE; } json_array_foreach(json_data, i, json_value) { @@ -223,7 +223,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm if (!sig) return -1; - enum signal_type fmt = json_detect_format(json_value); + enum SignalType fmt = json_detect_format(json_value); if (sig->type != fmt) { error("Received invalid data type in JSON payload: Received %s, expected %s for signal %s (index %zu).", signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i); @@ -238,7 +238,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm } if (smp->length > 0) - smp->flags |= SAMPLE_HAS_DATA; + smp->flags |= (int) SampleFlags::HAS_DATA; return 0; } @@ -362,24 +362,24 @@ skip: json = json_loadf(f, JSON_DISABLE_EOF_CHECK, &err); static struct plugin p; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "json"; p.description = "Javascript Object Notation"; - p.type = PLUGIN_TYPE_FORMAT; + p.type = PluginType::FORMAT; p.format.print = json_print; p.format.scan = json_scan; p.format.sprint = json_sprint; p.format.sscan = json_sscan; p.format.size = 0; - p.format.flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p.format.flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; p.format.delimiter = '\n'; vlist_push(&plugins, &p); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/formats/json_reserve.cpp b/lib/formats/json_reserve.cpp index 9acc935e9..18e1849a9 100644 --- a/lib/formats/json_reserve.cpp +++ b/lib/formats/json_reserve.cpp @@ -40,10 +40,10 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm json_t *json_created = NULL; json_t *json_sequence = NULL; - if (smp->flags & SAMPLE_HAS_TS_ORIGIN) + if (smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) json_created = json_integer(time_to_double(&smp->ts.origin) * 1e3); - if (smp->flags & SAMPLE_HAS_SEQUENCE) + if (smp->flags & (int) SampleFlags::HAS_SEQUENCE) json_sequence = json_integer(smp->sequence); json_data = json_array(); @@ -212,11 +212,11 @@ static int json_reserve_unpack_sample(struct io *io, json_t *json_smp, struct sa } if (smp->length > 0) - smp->flags |= SAMPLE_HAS_DATA; + smp->flags |= (int) SampleFlags::HAS_DATA; if (created > 0) { smp->ts.origin = time_from_double(created * 1e-3); - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; } return smp->length > 0 ? 1 : 0; @@ -326,22 +326,22 @@ skip: json = json_loadf(f, JSON_DISABLE_EOF_CHECK, &err); static struct plugin p; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "json.reserve"; p.description = "RESERVE JSON format"; - p.type = PLUGIN_TYPE_FORMAT; + p.type = PluginType::FORMAT; p.format.print = json_reserve_print; p.format.scan = json_reserve_scan; p.format.sprint = json_reserve_sprint; p.format.sscan = json_reserve_sscan; p.format.size = 0; - + vlist_push(&plugins, &p); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/formats/msg.cpp b/lib/formats/msg.cpp index 73a452f72..44acd2dad 100644 --- a/lib/formats/msg.cpp +++ b/lib/formats/msg.cpp @@ -81,7 +81,7 @@ int msg_to_sample(struct msg *msg, struct sample *smp, struct vlist *signals) if (ret) return -1; - smp->flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + smp->flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; smp->length = MIN(msg->length, smp->capacity); smp->sequence = msg->sequence; MSG_TS(msg, smp->ts.origin); @@ -90,11 +90,11 @@ int msg_to_sample(struct msg *msg, struct sample *smp, struct vlist *signals) struct signal *sig = (struct signal *) vlist_at(signals, i); switch (sig->type) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: smp->data[i].f = msg->data[i].f; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: smp->data[i].i = msg->data[i].i; break; @@ -119,11 +119,11 @@ int msg_from_sample(struct msg *msg_in, struct sample *smp, struct vlist *signal struct signal *sig = (struct signal *) vlist_at(signals, i); switch (sig->type) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: msg_in->data[i].f = smp->data[i].f; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: msg_in->data[i].i = smp->data[i].i; break; diff --git a/lib/formats/protobuf.cpp b/lib/formats/protobuf.cpp index f2c58e99e..2a4a02342 100644 --- a/lib/formats/protobuf.cpp +++ b/lib/formats/protobuf.cpp @@ -31,24 +31,24 @@ using namespace villas::utils; -static enum signal_type protobuf_detect_format(Villas__Node__Value *val) +static enum SignalType protobuf_detect_format(Villas__Node__Value *val) { switch (val->value_case) { case VILLAS__NODE__VALUE__VALUE_F: - return SIGNAL_TYPE_FLOAT; + return SignalType::FLOAT; case VILLAS__NODE__VALUE__VALUE_I: - return SIGNAL_TYPE_INTEGER; + return SignalType::INTEGER; case VILLAS__NODE__VALUE__VALUE_B: - return SIGNAL_TYPE_BOOLEAN; + return SignalType::BOOLEAN; case VILLAS__NODE__VALUE__VALUE_Z: - return SIGNAL_TYPE_COMPLEX; + return SignalType::COMPLEX; case VILLAS__NODE__VALUE__VALUE__NOT_SET: default: - return SIGNAL_TYPE_INVALID; + return SignalType::INVALID; } } @@ -70,12 +70,12 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct pb_smp->type = VILLAS__NODE__SAMPLE__TYPE__DATA; - if (io->flags & smp->flags & SAMPLE_HAS_SEQUENCE) { + if (io->flags & smp->flags & (int) SampleFlags::HAS_SEQUENCE) { pb_smp->has_sequence = 1; pb_smp->sequence = smp->sequence; } - if (io->flags & smp->flags & SAMPLE_HAS_TS_ORIGIN) { + if (io->flags & smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) { pb_smp->timestamp = (Villas__Node__Timestamp *) alloc(sizeof(Villas__Node__Timestamp)); villas__node__timestamp__init(pb_smp->timestamp); @@ -90,24 +90,24 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct Villas__Node__Value *pb_val = pb_smp->values[j] = (Villas__Node__Value *) alloc(sizeof(Villas__Node__Value)); villas__node__value__init(pb_val); - enum signal_type fmt = sample_format(smp, j); + enum SignalType fmt = sample_format(smp, j); switch (fmt) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: pb_val->value_case = VILLAS__NODE__VALUE__VALUE_F; pb_val->f = smp->data[j].f; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: pb_val->value_case = VILLAS__NODE__VALUE__VALUE_I; pb_val->i = smp->data[j].i; break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: pb_val->value_case = VILLAS__NODE__VALUE__VALUE_B; pb_val->b = smp->data[j].b; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: pb_val->value_case = VILLAS__NODE__VALUE__VALUE_Z; pb_val->z = (Villas__Node__Complex *) alloc(sizeof(Villas__Node__Complex)); @@ -117,7 +117,7 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct pb_val->z->imag = cimag(smp->data[j].z); break; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: pb_val->value_case = VILLAS__NODE__VALUE__VALUE__NOT_SET; break; } @@ -163,12 +163,12 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s } if (pb_smp->has_sequence) { - smp->flags |= SAMPLE_HAS_SEQUENCE; + smp->flags |= (int) SampleFlags::HAS_SEQUENCE; smp->sequence = pb_smp->sequence; } if (pb_smp->timestamp) { - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; smp->ts.origin.tv_sec = pb_smp->timestamp->sec; smp->ts.origin.tv_nsec = pb_smp->timestamp->nsec; } @@ -176,7 +176,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s for (j = 0; j < MIN(pb_smp->n_values, smp->capacity); j++) { Villas__Node__Value *pb_val = pb_smp->values[j]; - enum signal_type fmt = protobuf_detect_format(pb_val); + enum SignalType fmt = protobuf_detect_format(pb_val); struct signal *sig = (struct signal *) vlist_at_safe(smp->signals, j); if (!sig) @@ -189,19 +189,19 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s } switch (sig->type) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: smp->data[j].f = pb_val->f; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: smp->data[j].i = pb_val->i; break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: smp->data[j].b = pb_val->b; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: smp->data[j].z = pb_val->z->real + _Complex_I * pb_val->z->imag; break; @@ -210,7 +210,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s } if (pb_smp->n_values > 0) - smp->flags |= SAMPLE_HAS_DATA; + smp->flags |= (int) SampleFlags::HAS_DATA; smp->length = j; } @@ -226,22 +226,22 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s static struct plugin p; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "protobuf"; p.description = "Google Protobuf"; - p.type = PLUGIN_TYPE_FORMAT; + p.type = PluginType::FORMAT; p.format.sprint = protobuf_sprint; p.format.sscan = protobuf_sscan; - p.format.flags = IO_HAS_BINARY_PAYLOAD | - SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p.format.flags = (int) IOFlags::HAS_BINARY_PAYLOAD | + (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; vlist_push(&plugins, &p); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/formats/raw.cpp b/lib/formats/raw.cpp index b270f1ac4..09da1c4bd 100644 --- a/lib/formats/raw.cpp +++ b/lib/formats/raw.cpp @@ -118,16 +118,16 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp } for (unsigned j = 0; j < smp->length; j++) { - enum signal_type fmt = sample_format(smp, j); + enum SignalType fmt = sample_format(smp, j); union signal_data *data = &smp->data[j]; /* Check length */ - nlen = (o + fmt == SIGNAL_TYPE_COMPLEX ? 2 : 1) * (bits / 8); + nlen = (o + (fmt == SignalType::COMPLEX ? 2 : 1)) * (bits / 8); if (nlen >= len) goto out; switch (fmt) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: switch (bits) { case 8: i8 [o++] = -1; @@ -151,7 +151,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp } break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: switch (bits) { case 8: i8 [o++] = data->i; @@ -177,7 +177,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp } break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: switch (bits) { case 8: i8 [o++] = data->b ? 1 : 0; @@ -203,7 +203,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp } break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: switch (bits) { case 8: i8 [o++] = -1; /* Not supported */ @@ -233,7 +233,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp } break; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: return -1; } } @@ -313,7 +313,7 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct #endif } - smp->flags = SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_TS_ORIGIN; + smp->flags = (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_TS_ORIGIN; } else { smp->flags = 0; @@ -326,11 +326,11 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct unsigned i; for (i = 0; i < smp->capacity && o < nlen; i++) { - enum signal_type fmt = sample_format(smp, i); + enum SignalType fmt = sample_format(smp, i); union signal_data *data = &smp->data[i]; switch (fmt) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: switch (bits) { case 8: data->f = -1; o++; break; /* Not supported */ case 16: data->f = -1; o++; break; /* Not supported */ @@ -343,7 +343,7 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct } break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: switch (bits) { case 8: data->i = (int8_t) i8[o++]; break; case 16: data->i = (int16_t) SWAP_INT_XTOH(io->flags & RAW_BIG_ENDIAN, 16, i16[o++]); break; @@ -355,7 +355,7 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct } break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: switch (bits) { case 8: data->b = (bool) i8[o++]; break; case 16: data->b = (bool) SWAP_INT_XTOH(io->flags & RAW_BIG_ENDIAN, 16, i16[o++]); break; @@ -367,7 +367,7 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct } break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: switch (bits) { case 8: data->z = -1 + _Complex_I * -1; o += 2; break; /* Not supported */ case 16: data->z = -1 + _Complex_I * -1; o += 2; break; /* Not supported */ @@ -389,7 +389,7 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct } break; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: warning("Unsupported format in RAW payload"); return -1; } @@ -411,22 +411,22 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct #define REGISTER_FORMAT_RAW(i, n, d, f) \ static struct plugin i; \ __attribute__((constructor(110))) static void UNIQUE(__ctor)() { \ - if (plugins.state == STATE_DESTROYED) \ + if (plugins.state == State::DESTROYED) \ vlist_init(&plugins); \ \ i.name = n; \ i.description = d; \ - i.type = PLUGIN_TYPE_FORMAT; \ + i.type = PluginType::FORMAT; \ i.format.sprint = raw_sprint; \ i.format.sscan = raw_sscan; \ - i.format.flags = f | IO_HAS_BINARY_PAYLOAD | \ - SAMPLE_HAS_DATA; \ + i.format.flags = f | (int) IOFlags::HAS_BINARY_PAYLOAD | \ + (int) SampleFlags::HAS_DATA; \ \ vlist_push(&plugins, &i); \ } \ \ __attribute__((destructor(110))) static void UNIQUE(__dtor)() { \ - if (plugins.state != STATE_DESTROYED) \ + if (plugins.state != State::DESTROYED) \ vlist_remove_all(&plugins, &i); \ } /* Feel free to add additional format identifiers here to suit your needs */ diff --git a/lib/formats/villas_binary.cpp b/lib/formats/villas_binary.cpp index c3d7993ae..b9526514d 100644 --- a/lib/formats/villas_binary.cpp +++ b/lib/formats/villas_binary.cpp @@ -121,23 +121,23 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt static struct plugin p1; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p1.name = "villas.binary"; p1.description = "VILLAS binary network format"; - p1.type = PLUGIN_TYPE_FORMAT; + p1.type = PluginType::FORMAT; p1.format.sprint = villas_binary_sprint; p1.format.sscan = villas_binary_sscan; p1.format.size = 0; - p1.format.flags = IO_HAS_BINARY_PAYLOAD | - SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p1.format.flags = (int) IOFlags::HAS_BINARY_PAYLOAD | + (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; vlist_push(&plugins, &p1); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p1); } /** The WebSocket node-type usually uses little endian byte order intead of network byte order */ @@ -145,22 +145,22 @@ static struct plugin p2; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p2.name = "villas.web"; p2.description = "VILLAS binary network format for WebSockets"; - p2.type = PLUGIN_TYPE_FORMAT; + p2.type = PluginType::FORMAT; p2.format.sprint = villas_binary_sprint; p2.format.sscan = villas_binary_sscan; p2.format.size = 0; - p2.format.flags = IO_HAS_BINARY_PAYLOAD | VILLAS_BINARY_WEB | - SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p2.format.flags = (int) IOFlags::HAS_BINARY_PAYLOAD | VILLAS_BINARY_WEB | + (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; vlist_push(&plugins, &p2); } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p2); } diff --git a/lib/formats/villas_human.cpp b/lib/formats/villas_human.cpp index 8e1432d2d..538ae5d25 100644 --- a/lib/formats/villas_human.cpp +++ b/lib/formats/villas_human.cpp @@ -37,8 +37,8 @@ static size_t villas_human_sprint_single(struct io *io, char *buf, size_t len, c size_t off = 0; struct signal *sig; - if (io->flags & SAMPLE_HAS_TS_ORIGIN) { - if (smp->flags & SAMPLE_HAS_TS_ORIGIN) { + if (io->flags & (int) SampleFlags::HAS_TS_ORIGIN) { + if (smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) { off += snprintf(buf + off, len - off, "%llu", (unsigned long long) smp->ts.origin.tv_sec); off += snprintf(buf + off, len - off, ".%09llu", (unsigned long long) smp->ts.origin.tv_nsec); } @@ -46,17 +46,17 @@ static size_t villas_human_sprint_single(struct io *io, char *buf, size_t len, c off += snprintf(buf + off, len - off, "nan.nan"); } - if (io->flags & SAMPLE_HAS_OFFSET) { - if (smp->flags & SAMPLE_HAS_TS_RECEIVED) + if (io->flags & (int) SampleFlags::HAS_OFFSET) { + if (smp->flags & (int) SampleFlags::HAS_TS_RECEIVED) off += snprintf(buf + off, len - off, "%+e", time_delta(&smp->ts.origin, &smp->ts.received)); } - if (io->flags & SAMPLE_HAS_SEQUENCE) { - if (io->flags & SAMPLE_HAS_SEQUENCE) + if (io->flags & (int) SampleFlags::HAS_SEQUENCE) { + if (io->flags & (int) SampleFlags::HAS_SEQUENCE) off += snprintf(buf + off, len - off, "(%" PRIu64 ")", smp->sequence); } - if (io->flags & SAMPLE_HAS_DATA) { + if (io->flags & (int) SampleFlags::HAS_DATA) { for (unsigned i = 0; i < smp->length; i++) { sig = (struct signal *) vlist_at_safe(smp->signals, i); if (!sig) @@ -94,7 +94,7 @@ static size_t villas_human_sscan_single(struct io *io, const char *buf, size_t l if (ptr == end || *end == io->delimiter) return -1; - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; /* Optional: nano seconds */ if (*end == '.') { @@ -113,7 +113,7 @@ static size_t villas_human_sscan_single(struct io *io, const char *buf, size_t l offset = strtof(ptr, &end); /* offset is ignored for now */ if (ptr != end) - smp->flags |= SAMPLE_HAS_OFFSET; + smp->flags |= (int) SampleFlags::HAS_OFFSET; else return -4; } @@ -124,7 +124,7 @@ static size_t villas_human_sscan_single(struct io *io, const char *buf, size_t l smp->sequence = strtoul(ptr, &end, 10); if (ptr != end) - smp->flags |= SAMPLE_HAS_SEQUENCE; + smp->flags |= (int) SampleFlags::HAS_SEQUENCE; else return -5; @@ -152,13 +152,13 @@ out: if (*end == io->delimiter) smp->length = i; if (smp->length > 0) - smp->flags |= SAMPLE_HAS_DATA; + smp->flags |= (int) SampleFlags::HAS_DATA; - if (smp->flags & SAMPLE_HAS_OFFSET) { + if (smp->flags & (int) SampleFlags::HAS_OFFSET) { struct timespec off = time_from_double(offset); smp->ts.received = time_add(&smp->ts.origin, &off); - smp->flags |= SAMPLE_HAS_TS_RECEIVED; + smp->flags |= (int) SampleFlags::HAS_TS_RECEIVED; } return end - buf; @@ -198,16 +198,16 @@ void villas_human_header(struct io *io, const struct sample *smp) fprintf(f, "# "); - if (io->flags & SAMPLE_HAS_TS_ORIGIN) + if (io->flags & (int) SampleFlags::HAS_TS_ORIGIN) fprintf(f, "seconds.nanoseconds"); - if (io->flags & SAMPLE_HAS_OFFSET) + if (io->flags & (int) SampleFlags::HAS_OFFSET) fprintf(f, "+offset"); - if (io->flags & SAMPLE_HAS_SEQUENCE) + if (io->flags & (int) SampleFlags::HAS_SEQUENCE) fprintf(f, "(sequence)"); - if (io->flags & SAMPLE_HAS_DATA) { + if (io->flags & (int) SampleFlags::HAS_DATA) { for (unsigned i = 0; i < MIN(smp->length, vlist_length(smp->signals)); i++) { struct signal *sig = (struct signal *) vlist_at(smp->signals, i); @@ -226,17 +226,17 @@ void villas_human_header(struct io *io, const struct sample *smp) static struct plugin p; __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "villas.human"; p.description = "VILLAS human readable format"; - p.type = PLUGIN_TYPE_FORMAT; + p.type = PluginType::FORMAT; p.format.header = villas_human_header; p.format.sprint = villas_human_sprint; p.format.sscan = villas_human_sscan; p.format.size = 0; - p.format.flags = IO_NEWLINES | SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + p.format.flags = (int) IOFlags::NEWLINES | (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; p.format.delimiter = '\n'; p.format.separator = '\t'; @@ -244,6 +244,6 @@ __attribute__((constructor(110))) static void UNIQUE(__ctor)() { } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/hook.cpp b/lib/hook.cpp index b00d4f66f..1c2249557 100644 --- a/lib/hook.cpp +++ b/lib/hook.cpp @@ -39,7 +39,7 @@ using namespace villas; using namespace villas::node; Hook::Hook(struct path *p, struct node *n, int fl, int prio, bool en) : - state(STATE_INITIALIZED), + state(State::INITIALIZED), flags(fl), priority(prio), enabled(en), @@ -50,14 +50,14 @@ Hook::Hook(struct path *p, struct node *n, int fl, int prio, bool en) : logger = logging.get("hook"); - signals.state = STATE_DESTROYED; + signals.state = State::DESTROYED; ret = signal_list_init(&signals); if (ret) throw RuntimeError("Failed to initialize signal list"); /* We dont need to parse builtin hooks. */ - state = flags & HOOK_BUILTIN ? STATE_CHECKED : STATE_INITIALIZED; + state = flags & (int) Hook::Flags::BUILTIN ? State::CHECKED : State::INITIALIZED; } Hook::~Hook() @@ -67,9 +67,9 @@ Hook::~Hook() void Hook::prepare() { - assert(state == STATE_CHECKED); + assert(state == State::CHECKED); - state = STATE_PREPARED; + state = State::PREPARED; } void Hook::parse(json_t *c) @@ -77,7 +77,7 @@ void Hook::parse(json_t *c) int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(c, &err, 0, "{ s?: i, s?: b }", "priority", &priority, @@ -88,5 +88,5 @@ void Hook::parse(json_t *c) cfg = c; - state = STATE_PARSED; + state = State::PARSED; } diff --git a/lib/hook_list.cpp b/lib/hook_list.cpp index 18116b567..33489f585 100644 --- a/lib/hook_list.cpp +++ b/lib/hook_list.cpp @@ -102,7 +102,7 @@ static int hook_is_enabled(const Hook *h) void hook_list_prepare(vlist *hs, vlist *sigs, int m, struct path *p, struct node *n) { - assert(hs->state == STATE_INITIALIZED); + assert(hs->state == State::INITIALIZED); if (!m) goto skip_add; @@ -134,7 +134,7 @@ skip_add: int hook_list_process(vlist *hs, sample *smps[], unsigned cnt) { - unsigned ret, current, processed = 0; + unsigned current, processed = 0; if (vlist_length(hs) == 0) return cnt; @@ -145,18 +145,18 @@ int hook_list_process(vlist *hs, sample *smps[], unsigned cnt) for (size_t i = 0; i < vlist_length(hs); i++) { Hook *h = (Hook *) vlist_at(hs, i); - ret = h->process(smp); + auto ret = h->process(smp); switch (ret) { - case HOOK_ERROR: + case Hook::Reason::ERROR: return -1; - case HOOK_OK: + case Hook::Reason::OK: continue; - case HOOK_SKIP_SAMPLE: + case Hook::Reason::SKIP_SAMPLE: goto skip; - case HOOK_STOP_PROCESSING: + case Hook::Reason::STOP_PROCESSING: goto stop; } } diff --git a/lib/hooks/average.cpp b/lib/hooks/average.cpp index 4cd713c92..203b92206 100644 --- a/lib/hooks/average.cpp +++ b/lib/hooks/average.cpp @@ -54,7 +54,7 @@ public: if (ret) throw RuntimeError("Failed to intialize list"); - state = STATE_INITIALIZED; + state = State::INITIALIZED; } virtual ~AverageHook() @@ -67,7 +67,7 @@ public: int ret; struct signal *avg_sig; - assert(state == STATE_CHECKED); + assert(state == State::CHECKED); /* Setup mask */ for (size_t i = 0; i < vlist_length(&signal_names); i++) { @@ -84,7 +84,7 @@ public: throw RuntimeError("Invalid signal mask"); /* Add averaged signal */ - avg_sig = signal_create("average", nullptr, SIGNAL_TYPE_FLOAT); + avg_sig = signal_create("average", nullptr, SignalType::FLOAT); if (!avg_sig) throw RuntimeError("Failed to create new signal"); @@ -92,7 +92,7 @@ public: if (ret) throw RuntimeError("Failed to intialize list"); - state = STATE_PREPARED; + state = State::PREPARED; } virtual void parse(json_t *cfg) @@ -102,7 +102,7 @@ public: json_error_t err; json_t *json_signals, *json_signal; - assert(state != STATE_STARTED); + assert(state != State::STARTED); Hook::parse(cfg); @@ -131,33 +131,33 @@ public: } } - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { double avg, sum = 0; int n = 0; - assert(state == STATE_STARTED); + assert(state == State::STARTED); for (unsigned k = 0; k < smp->length; k++) { if (!mask.test(k)) continue; switch (sample_format(smp, k)) { - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: sum += smp->data[k].i; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: sum += smp->data[k].f; break; - case SIGNAL_TYPE_INVALID: - case SIGNAL_TYPE_COMPLEX: - case SIGNAL_TYPE_BOOLEAN: - return HOOK_ERROR; /* not supported */ + case SignalType::INVALID: + case SignalType::COMPLEX: + case SignalType::BOOLEAN: + return Hook::Reason::ERROR; /* not supported */ } n++; @@ -167,7 +167,7 @@ public: sample_data_insert(smp, (union signal_data *) &avg, offset, 1); smp->signals = &signals; - return HOOK_OK; + return Reason::OK; } }; @@ -175,7 +175,7 @@ public: static HookPlugin p( "average", "Calculate average over some signals", - HOOK_PATH | HOOK_NODE_READ | HOOK_NODE_WRITE, + (int) Hook::Flags::PATH | (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE, 99 ); diff --git a/lib/hooks/cast.cpp b/lib/hooks/cast.cpp index 2cd5c1589..fed533b9e 100644 --- a/lib/hooks/cast.cpp +++ b/lib/hooks/cast.cpp @@ -39,7 +39,7 @@ protected: unsigned signal_index; char *signal_name; - enum signal_type new_type; + enum SignalType new_type; char *new_name; char *new_unit; @@ -48,7 +48,7 @@ public: Hook(p, n, fl, prio, en), signal_index(-1), signal_name(nullptr), - new_type(SIGNAL_TYPE_INVALID), + new_type(SignalType::INVALID), new_name(nullptr), new_unit(nullptr) { } @@ -69,7 +69,7 @@ public: { struct signal *orig_sig, *new_sig; - assert(state == STATE_CHECKED); + assert(state == State::CHECKED); if (signal_name) { signal_index = vlist_lookup_index(&signals, signal_name); @@ -78,13 +78,13 @@ public: } char *name, *unit; - enum signal_type type; + enum SignalType type; orig_sig = (struct signal *) vlist_at_safe(&signals, signal_index); if (!orig_sig) throw RuntimeError("Failed to find signal: {}", signal_name); - type = new_type != SIGNAL_TYPE_INVALID ? new_type : orig_sig->type; + type = new_type != SignalType::INVALID ? new_type : orig_sig->type; name = new_name ? new_name : orig_sig->name; unit = new_unit ? new_unit : orig_sig->unit; @@ -93,7 +93,7 @@ public: vlist_set(&signals, signal_index, new_sig); signal_decref(orig_sig); - state = STATE_PREPARED; + state = State::PREPARED; } virtual void parse(json_t *cfg) @@ -103,7 +103,7 @@ public: json_error_t err; json_t *json_signal; - assert(state != STATE_STARTED); + assert(state != State::STARTED); const char *name = nullptr; const char *unit = nullptr; @@ -134,12 +134,12 @@ public: if (type) { new_type = signal_type_from_str(type); - if (new_type == SIGNAL_TYPE_INVALID) + if (new_type == SignalType::INVALID) throw RuntimeError("Invalid signal type: {}", type); } else /* We use this constant to indicate that we dont want to change the type. */ - new_type = SIGNAL_TYPE_INVALID; + new_type = SignalType::INVALID; if (name) new_name = strdup(name); @@ -147,12 +147,12 @@ public: if (unit) new_unit = strdup(unit); - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); struct signal *orig_sig = (struct signal *) vlist_at(smp->signals, signal_index); struct signal *new_sig = (struct signal *) vlist_at(&signals, signal_index); @@ -162,7 +162,7 @@ public: /* Replace signal descriptors of sample */ smp->signals = &signals; - return HOOK_OK; + return Reason::OK; } }; @@ -170,7 +170,7 @@ public: static HookPlugin p( "cast", "Cast signals types", - HOOK_NODE_READ | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/decimate.cpp b/lib/hooks/decimate.cpp index d7ab94119..b99b0356d 100644 --- a/lib/hooks/decimate.cpp +++ b/lib/hooks/decimate.cpp @@ -31,11 +31,11 @@ namespace node { void DecimateHook::start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); counter = 0; - state = STATE_STARTED; + state = State::STARTED; } void DecimateHook::parse(json_t *cfg) @@ -43,7 +43,7 @@ void DecimateHook::parse(json_t *cfg) int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", "ratio", &ratio @@ -51,24 +51,24 @@ void DecimateHook::parse(json_t *cfg) if (ret) throw ConfigError(cfg, err, "node-config-hook-decimate"); - state = STATE_PARSED; + state = State::PARSED; } -int DecimateHook::process(sample *smp) +Hook::Reason DecimateHook::process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (ratio && counter++ % ratio != 0) - return HOOK_SKIP_SAMPLE; + return Hook::Reason::SKIP_SAMPLE; - return HOOK_OK; + return Reason::OK; } /* Register hook */ static HookPlugin p( "decimate", "Downsamping by integer factor", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/dp.cpp b/lib/hooks/dp.cpp index d5fc6fd4c..c650c57f6 100644 --- a/lib/hooks/dp.cpp +++ b/lib/hooks/dp.cpp @@ -136,7 +136,7 @@ public: virtual void start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); time = 0; steps = 0; @@ -146,7 +146,7 @@ public: window = dsp::Window((1.0 / f0) / timestep, 0.0); - state = STATE_STARTED; + state = State::STARTED; } virtual void parse(json_t *cfg) @@ -206,19 +206,19 @@ public: fharmonics[i] = json_integer_value(json_harmonic); } - state = STATE_PARSED; + state = State::PARSED; } virtual void prepare() { int ret; - assert(state == STATE_CHECKED); + assert(state == State::CHECKED); char *new_sig_name; struct signal *orig_sig, *new_sig; - assert(state != STATE_STARTED); + assert(state != State::STARTED); if (signal_name) { signal_index = vlist_lookup_index(&signals, signal_name); @@ -233,7 +233,7 @@ public: if (!orig_sig) throw RuntimeError("Failed to find signal");; - if (orig_sig->type != SIGNAL_TYPE_COMPLEX) + if (orig_sig->type != SignalType::COMPLEX) throw RuntimeError("Signal is not complex");; ret = vlist_remove(&signals, signal_index + i); @@ -244,7 +244,7 @@ public: } /* Add new real-valued reconstructed signals */ - new_sig = signal_create("dp", "idp", SIGNAL_TYPE_FLOAT); + new_sig = signal_create("dp", "idp", SignalType::FLOAT); if (!new_sig) throw RuntimeError("Failed to create signal");; @@ -257,7 +257,7 @@ public: if (!orig_sig) throw RuntimeError("Failed to find signal");; - if (orig_sig->type != SIGNAL_TYPE_FLOAT) + if (orig_sig->type != SignalType::FLOAT) throw RuntimeError("Signal is not float");; ret = vlist_remove(&signals, signal_index); @@ -267,7 +267,7 @@ public: for (int i = 0; i < fharmonics_len; i++) { new_sig_name = strf("%s_harm%d", orig_sig->name, i); - new_sig = signal_create(new_sig_name, orig_sig->unit, SIGNAL_TYPE_COMPLEX); + new_sig = signal_create(new_sig_name, orig_sig->unit, SignalType::COMPLEX); if (!new_sig) throw RuntimeError("Failed to create new signal");; @@ -279,13 +279,13 @@ public: signal_decref(orig_sig); } - state = STATE_PREPARED; + state = State::PREPARED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { if (signal_index > smp->length) - return HOOK_ERROR; + return Hook::Reason::ERROR; if (inverse) { double signal; @@ -311,7 +311,7 @@ public: time += timestep; steps++; - return HOOK_OK; + return Reason::OK; } }; @@ -319,7 +319,7 @@ public: static HookPlugin p( "dp", "Transform to/from dynamic phasor domain", - HOOK_PATH | HOOK_NODE_READ | HOOK_NODE_WRITE, + (int) Hook::Flags::PATH | (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE, 99 ); diff --git a/lib/hooks/drop.cpp b/lib/hooks/drop.cpp index ec0fc6960..e80894828 100644 --- a/lib/hooks/drop.cpp +++ b/lib/hooks/drop.cpp @@ -43,35 +43,35 @@ public: virtual void start() { - assert(state == STATE_PREPARED || state == STATE_STOPPED); + assert(state == State::PREPARED || state == State::STOPPED); prev = nullptr; - state = STATE_STARTED; + state = State::STARTED; } virtual void stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (prev) sample_decref(prev); - state = STATE_STOPPED; + state = State::STOPPED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { int dist; - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (prev) { dist = smp->sequence - (int64_t) prev->sequence; if (dist <= 0) { logger->debug("Dropping reordered sample: sequence={}, distance={}", smp->sequence, dist); - return HOOK_SKIP_SAMPLE; + return Hook::Reason::SKIP_SAMPLE; } } @@ -81,12 +81,12 @@ public: prev = smp; - return HOOK_OK; + return Reason::OK; } virtual void restart() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (prev) { sample_decref(prev); @@ -99,7 +99,7 @@ public: static HookPlugin p( "drop", "Drop messages with reordered sequence numbers", - HOOK_BUILTIN | HOOK_NODE_READ, + (int) Hook::Flags::BUILTIN | (int) Hook::Flags::NODE_READ, 3 ); diff --git a/lib/hooks/dump.cpp b/lib/hooks/dump.cpp index 4230beba2..c15e46e82 100644 --- a/lib/hooks/dump.cpp +++ b/lib/hooks/dump.cpp @@ -37,13 +37,13 @@ class DumpHook : public Hook { public: using Hook::Hook; - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); sample_dump(smp); - return HOOK_OK; + return Reason::OK; } }; @@ -51,7 +51,7 @@ public: static HookPlugin p( "dump", "Dump data to stdout", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 1 ); diff --git a/lib/hooks/ebm.cpp b/lib/hooks/ebm.cpp index bc2075c39..f45072bd7 100644 --- a/lib/hooks/ebm.cpp +++ b/lib/hooks/ebm.cpp @@ -75,31 +75,31 @@ public: phases.emplace_back(voltage, current); } - state = STATE_PARSED; + state = State::PARSED; } virtual void start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); energy = 0; last = nullptr; - state = STATE_STARTED; + state = State::STARTED; } virtual void periodic() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); info("Energy: %f", energy); } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { double P, P_last, dt; - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (last) { for (auto phase : phases) { @@ -118,14 +118,14 @@ public: sample_incref(smp); last = smp; - return HOOK_OK; + return Reason::OK; } }; static HookPlugin p( "ebm", "Energy-based Metric", - HOOK_PATH | HOOK_NODE_READ | HOOK_NODE_WRITE, + (int) Hook::Flags::PATH | (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE, 99 ); diff --git a/lib/hooks/fix.cpp b/lib/hooks/fix.cpp index 3dffe878c..5b1239ebb 100644 --- a/lib/hooks/fix.cpp +++ b/lib/hooks/fix.cpp @@ -40,28 +40,28 @@ class FixHook : public Hook { public: using Hook::Hook; - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); timespec now = time_now(); - if (!(smp->flags & SAMPLE_HAS_SEQUENCE) && node) { + if (!(smp->flags & (int) SampleFlags::HAS_SEQUENCE) && node) { smp->sequence = node->sequence++; - smp->flags |= SAMPLE_HAS_SEQUENCE; + smp->flags |= (int) SampleFlags::HAS_SEQUENCE; } - if (!(smp->flags & SAMPLE_HAS_TS_RECEIVED)) { + if (!(smp->flags & (int) SampleFlags::HAS_TS_RECEIVED)) { smp->ts.received = now; - smp->flags |= SAMPLE_HAS_TS_RECEIVED; + smp->flags |= (int) SampleFlags::HAS_TS_RECEIVED; } - if (!(smp->flags & SAMPLE_HAS_TS_ORIGIN)) { + if (!(smp->flags & (int) SampleFlags::HAS_TS_ORIGIN)) { smp->ts.origin = smp->ts.received; - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; } - return HOOK_OK; + return Reason::OK; } }; @@ -69,7 +69,7 @@ public: static HookPlugin p( "fix", "Fix received data by adding missing fields", - HOOK_BUILTIN | HOOK_NODE_READ, + (int) Hook::Flags::BUILTIN | (int) Hook::Flags::NODE_READ, 1 ); diff --git a/lib/hooks/jitter_calc.cpp b/lib/hooks/jitter_calc.cpp index 42f4aa101..a247815fa 100644 --- a/lib/hooks/jitter_calc.cpp +++ b/lib/hooks/jitter_calc.cpp @@ -86,9 +86,9 @@ public: * is high (i.e. several mins depending on GPS_NTP_DELAY_WIN_SIZE), * the variance value will overrun the 64bit value. */ - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); timespec now = time_now(); int64_t delay_sec, delay_nsec, curr_delay_us; @@ -119,7 +119,7 @@ public: if (curr_count >= GPS_NTP_DELAY_WIN_SIZE) curr_count = 0; - return HOOK_OK; + return Reason::OK; } }; @@ -127,7 +127,7 @@ public: static HookPlugin p( "jitter_calc", "Calc jitter, mean and variance of GPS vs NTP TS", - HOOK_NODE_READ | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::PATH, 0 ); diff --git a/lib/hooks/limit_rate.cpp b/lib/hooks/limit_rate.cpp index 6886e4738..887bfc68b 100644 --- a/lib/hooks/limit_rate.cpp +++ b/lib/hooks/limit_rate.cpp @@ -38,7 +38,7 @@ void LimitRateHook::parse(json_t *cfg) int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); double rate; const char *m = nullptr; @@ -63,12 +63,12 @@ void LimitRateHook::parse(json_t *cfg) deadtime = 1.0 / rate; - state = STATE_PARSED; + state = State::PARSED; } -int LimitRateHook::process(sample *smp) +Hook::Reason LimitRateHook::process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); timespec next; switch (mode) { @@ -86,18 +86,18 @@ int LimitRateHook::process(sample *smp) } if (time_delta(&last, &next) < deadtime) - return HOOK_SKIP_SAMPLE; + return Hook::Reason::SKIP_SAMPLE; last = next; - return HOOK_OK; + return Reason::OK; } /* Register hook */ static HookPlugin p( "limit_rate", "Limit sending rate", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/print.cpp b/lib/hooks/print.cpp index d002662b1..5b955d093 100644 --- a/lib/hooks/print.cpp +++ b/lib/hooks/print.cpp @@ -50,7 +50,7 @@ public: prefix(nullptr), uri(nullptr) { - io.state = STATE_DESTROYED; + io.state = State::DESTROYED; format = format_type_lookup("villas.human"); } @@ -59,9 +59,9 @@ public: { int ret; - assert(state == STATE_PREPARED || state == STATE_STOPPED); + assert(state == State::PREPARED || state == State::STOPPED); - ret = io_init(&io, format, &signals, SAMPLE_HAS_ALL); + ret = io_init(&io, format, &signals, (int) SampleFlags::HAS_ALL); if (ret) throw RuntimeError("Failed to initialze IO"); @@ -73,14 +73,14 @@ public: if (ret) throw RuntimeError("Failed to open IO"); - state = STATE_STARTED; + state = State::STARTED; } virtual void stop() { int ret; - assert(state == STATE_STARTED); + assert(state == State::STARTED); ret = io_close(&io); if (ret) @@ -90,7 +90,7 @@ public: if (ret) throw RuntimeError("Failed to destroy IO"); - state = STATE_STOPPED; + state = State::STOPPED; } virtual void parse(json_t *cfg) @@ -99,7 +99,7 @@ public: int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s }", "output", &u, @@ -121,12 +121,12 @@ public: throw ConfigError(cfg, "node-config-hook-print-format", "Invalid IO format '{}'", f); } - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (prefix) printf("%s", prefix); @@ -137,7 +137,7 @@ public: io_print(&io, &smp, 1); - return HOOK_OK; + return Reason::OK; } virtual ~PrintHook() @@ -154,7 +154,7 @@ public: static HookPlugin p( "print", "Print the message to stdout", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/restart.cpp b/lib/hooks/restart.cpp index 7db41622e..838850723 100644 --- a/lib/hooks/restart.cpp +++ b/lib/hooks/restart.cpp @@ -43,26 +43,26 @@ public: virtual void start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); prev = nullptr; - state = STATE_STARTED; + state = State::STARTED; } virtual void stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (prev) sample_decref(prev); - state = STATE_STOPPED; + state = State::STOPPED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (prev) { /* A wrap around of the sequence no should not be treated as a simulation restart */ @@ -70,7 +70,7 @@ public: logger->warn("Simulation from node {} restarted (previous->sequence={}, current->sequence={})", node_name(node), prev->sequence, smp->sequence); - smp->flags |= SAMPLE_IS_FIRST; + smp->flags |= (int) SampleFlags::IS_FIRST; /* Restart hooks */ for (size_t i = 0; i < vlist_length(&node->in.hooks); i++) { @@ -93,7 +93,7 @@ public: prev = smp; - return HOOK_OK; + return Reason::OK; } }; @@ -101,7 +101,7 @@ public: static HookPlugin p( "restart", "Call restart hooks for current node", - HOOK_BUILTIN | HOOK_NODE_READ, + (int) Hook::Flags::BUILTIN | (int) Hook::Flags::NODE_READ, 1 ); diff --git a/lib/hooks/scale.cpp b/lib/hooks/scale.cpp index 929cf2740..b470ff190 100644 --- a/lib/hooks/scale.cpp +++ b/lib/hooks/scale.cpp @@ -50,7 +50,7 @@ public: virtual void prepare() { - assert(state != STATE_STARTED); + assert(state != State::STARTED); if (signal_name) { signal_index = vlist_lookup_index(&signals, signal_name); @@ -58,7 +58,7 @@ public: throw RuntimeError("Failed to find signal: {}", signal_name); } - state = STATE_PREPARED; + state = State::PREPARED; } virtual ~ScaleHook() @@ -73,7 +73,7 @@ public: json_t *json_signal; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s?: F, s?: F, s: o }", "scale", &scale, @@ -97,36 +97,36 @@ public: throw ConfigError(json_signal, "node-config-hook-scale-signal", "Invalid value for setting 'signal'"); } - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { int k = signal_index; - assert(state == STATE_STARTED); + assert(state == State::STARTED); switch (sample_format(smp, k)) { - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: smp->data[k].i = smp->data[k].i * scale + offset; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: smp->data[k].f = smp->data[k].f * scale + offset; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: smp->data[k].z = smp->data[k].z * scale + offset; break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: smp->data[k].b = smp->data[k].b * scale + offset; break; default: { } } - return HOOK_OK; + return Reason::OK; } }; @@ -134,7 +134,7 @@ public: static HookPlugin p( "scale", "Scale signals by a factor and add offset", - HOOK_PATH | HOOK_NODE_READ | HOOK_NODE_WRITE, + (int) Hook::Flags::PATH | (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE, 99 ); diff --git a/lib/hooks/shift_seq.cpp b/lib/hooks/shift_seq.cpp index f9b60efda..ca2ecf469 100644 --- a/lib/hooks/shift_seq.cpp +++ b/lib/hooks/shift_seq.cpp @@ -44,7 +44,7 @@ public: json_error_t err; int ret; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", "offset", &offset @@ -52,16 +52,16 @@ public: if (ret) throw ConfigError(cfg, err, "node-config-hook-shift_seq"); - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); smp->sequence += offset; - return HOOK_OK; + return Reason::OK; } }; @@ -69,7 +69,7 @@ public: static HookPlugin p( "shift_seq", "Shift sequence number of samples", - HOOK_NODE_READ | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/shift_ts.cpp b/lib/hooks/shift_ts.cpp index 85a413a8c..96c014e06 100644 --- a/lib/hooks/shift_ts.cpp +++ b/lib/hooks/shift_ts.cpp @@ -55,7 +55,7 @@ public: int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s: F }", "mode", &m, @@ -75,14 +75,14 @@ public: offset = time_from_double(o); - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { timespec *ts; - assert(state == STATE_STARTED); + assert(state == State::STARTED); switch (mode) { case SHIFT_ORIGIN: @@ -94,12 +94,12 @@ public: break; default: - return HOOK_ERROR; + return Hook::Reason::ERROR; } *ts = time_add(ts, &offset);; - return HOOK_OK; + return Reason::OK; } }; @@ -107,7 +107,7 @@ public: static HookPlugin p( "shift_ts", "Shift timestamps of samples", - HOOK_NODE_READ | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/skip_first.cpp b/lib/hooks/skip_first.cpp index 0aaf0ee92..0900dcad2 100644 --- a/lib/hooks/skip_first.cpp +++ b/lib/hooks/skip_first.cpp @@ -34,15 +34,15 @@ namespace node { class SkipFirstHook : public Hook { protected: - enum { - HOOK_SKIP_FIRST_STATE_STARTED, /**< Path just started. First sample not received yet. */ - HOOK_SKIP_FIRST_STATE_SKIPPING, /**< First sample received. Skipping samples now. */ - HOOK_SKIP_FIRST_STATE_NORMAL /**< All samples skipped. Normal operation. */ + enum class SkipState { + STARTED, /**< Path just started. First sample not received yet. */ + SKIPPING, /**< First sample received. Skipping samples now. */ + NORMAL /**< All samples skipped. Normal operation. */ } skip_state; - enum { - HOOK_SKIP_MODE_SECONDS, - HOOK_SKIP_MODE_SAMPLES + enum class Mode { + SECONDS, + SAMPLES } mode; union { @@ -67,22 +67,22 @@ public: int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s: F }", "seconds", &s); if (!ret) { seconds.wait = time_from_double(s); - mode = HOOK_SKIP_MODE_SECONDS; + mode = Mode::SECONDS; - state = STATE_PARSED; + state = State::PARSED; return; } ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", "samples", &samples.wait); if (!ret) { - mode = HOOK_SKIP_MODE_SAMPLES; + mode = Mode::SAMPLES; - state = STATE_PARSED; + state = State::PARSED; return; } @@ -91,44 +91,44 @@ public: virtual void restart() { - skip_state = HOOK_SKIP_FIRST_STATE_STARTED; + skip_state = SkipState::STARTED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); /* Remember sequence no or timestamp of first sample. */ - if (skip_state == HOOK_SKIP_FIRST_STATE_STARTED) { + if (skip_state == SkipState::STARTED) { switch (mode) { - case HOOK_SKIP_MODE_SAMPLES: + case Mode::SAMPLES: samples.until = smp->sequence + samples.wait; break; - case HOOK_SKIP_MODE_SECONDS: + case Mode::SECONDS: seconds.until = time_add(&smp->ts.origin, &seconds.wait); break; } - skip_state = HOOK_SKIP_FIRST_STATE_SKIPPING; + skip_state = SkipState::SKIPPING; } switch (mode) { - case HOOK_SKIP_MODE_SAMPLES: + case Mode::SAMPLES: if (samples.until > smp->sequence) - return HOOK_SKIP_SAMPLE; + return Hook::Reason::SKIP_SAMPLE; break; - case HOOK_SKIP_MODE_SECONDS: + case Mode::SECONDS: if (time_delta(&seconds.until, &smp->ts.origin) < 0) - return HOOK_SKIP_SAMPLE; + return Hook::Reason::SKIP_SAMPLE; break; default: break; } - return HOOK_OK; + return Reason::OK; } }; @@ -136,7 +136,7 @@ public: static HookPlugin p( "skip_first", "Skip the first samples", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp index 21708efa5..9439dd1ab 100644 --- a/lib/hooks/stats.cpp +++ b/lib/hooks/stats.cpp @@ -48,10 +48,10 @@ public: StatsWriteHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : Hook(p, n, fl, prio, en) { - state = STATE_CHECKED; + state = State::CHECKED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { Stats *s = node->stats; @@ -59,7 +59,7 @@ public: s->update(Stats::Metric::AGE, time_delta(&smp->ts.received, &now)); - return HOOK_OK; + return Reason::OK; } }; @@ -72,43 +72,43 @@ public: StatsReadHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : Hook(p, n, fl, prio, en) { - state = STATE_CHECKED; + state = State::CHECKED; } virtual void start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); last = nullptr; - state = STATE_STARTED; + state = State::STARTED; } virtual void stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); if (last) sample_decref(last); - state = STATE_STOPPED; + state = State::STOPPED; } - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { Stats *s = node->stats; if (last) { - if (smp->flags & last->flags & SAMPLE_HAS_TS_RECEIVED) + if (smp->flags & last->flags & (int) SampleFlags::HAS_TS_RECEIVED) s->update(Stats::Metric::GAP_RECEIVED, time_delta(&last->ts.received, &smp->ts.received)); - if (smp->flags & last->flags & SAMPLE_HAS_TS_ORIGIN) + if (smp->flags & last->flags & (int) SampleFlags::HAS_TS_ORIGIN) s->update(Stats::Metric::GAP_SAMPLE, time_delta(&last->ts.origin, &smp->ts.origin)); - if ((smp->flags & SAMPLE_HAS_TS_ORIGIN) && (smp->flags & SAMPLE_HAS_TS_RECEIVED)) + if ((smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) && (smp->flags & (int) SampleFlags::HAS_TS_RECEIVED)) s->update(Stats::Metric::OWD, time_delta(&smp->ts.origin, &smp->ts.received)); - if (smp->flags & last->flags & SAMPLE_HAS_SEQUENCE) { + if (smp->flags & last->flags & (int) SampleFlags::HAS_SEQUENCE) { int dist = smp->sequence - (int32_t) last->sequence; if (dist != 1) s->update(Stats::Metric::SMPS_REORDERED, dist); @@ -122,7 +122,7 @@ public: last = smp; - return HOOK_OK; + return Reason::OK; } }; @@ -177,7 +177,7 @@ public: virtual void start() { - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); if (uri) { output = afopen(uri, "w+"); @@ -185,31 +185,31 @@ public: throw RuntimeError("Failed to open file '{}' for writing", uri); } - state = STATE_STARTED; + state = State::STARTED; } virtual void stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); stats.print(uri ? output->file : stdout, format, verbose); if (uri) afclose(output); - state = STATE_STOPPED; + state = State::STOPPED; } virtual void restart() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); stats.reset(); } virtual void periodic() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); stats.printPeriodic(uri ? output->file : stdout, format, node); } @@ -219,7 +219,7 @@ public: int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); const char *f = nullptr; const char *u = nullptr; @@ -245,7 +245,7 @@ public: if (u) uri = strdup(u); - state = STATE_PARSED; + state = State::PARSED; } }; @@ -253,7 +253,7 @@ public: static HookPlugin p( "stats", "Collect statistics for the current path", - HOOK_NODE_READ, + (int) Hook::Flags::NODE_READ, 99 ); diff --git a/lib/hooks/ts.cpp b/lib/hooks/ts.cpp index fa0485dc8..71813574f 100644 --- a/lib/hooks/ts.cpp +++ b/lib/hooks/ts.cpp @@ -36,13 +36,13 @@ class TsHook : public Hook { public: using Hook::Hook; - virtual int process(sample *smp) + virtual Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); smp->ts.origin = smp->ts.received; - return HOOK_OK; + return Reason::OK; } }; @@ -50,7 +50,7 @@ public: static HookPlugin p( "ts", "Overwrite origin timestamp of samples with receive timestamp", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 99 ); diff --git a/lib/io.cpp b/lib/io.cpp index 98da97394..c20dacc68 100644 --- a/lib/io.cpp +++ b/lib/io.cpp @@ -87,12 +87,12 @@ int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals, { int ret; - assert(io->state == STATE_DESTROYED); + assert(io->state == State::DESTROYED); io->_vt = fmt; io->_vd = alloc(fmt->size); - io->flags = flags | (io_type(io)->flags & ~SAMPLE_HAS_ALL); + io->flags = flags | (io_type(io)->flags & ~(int) SampleFlags::HAS_ALL); io->delimiter = io_type(io)->delimiter ? io_type(io)->delimiter : '\n'; io->separator = io_type(io)->separator ? io_type(io)->separator : '\t'; @@ -108,7 +108,7 @@ int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals, if (ret) return ret; - io->state = STATE_INITIALIZED; + io->state = State::INITIALIZED; return 0; } @@ -119,7 +119,7 @@ int io_init2(struct io *io, const struct format_type *fmt, const char *dt, int f struct vlist *signals; signals = (struct vlist *) alloc(sizeof(struct vlist)); - signals->state = STATE_DESTROYED; + signals->state = State::DESTROYED; ret = vlist_init(signals); if (ret) @@ -129,7 +129,7 @@ int io_init2(struct io *io, const struct format_type *fmt, const char *dt, int f if (ret) return ret; - flags |= IO_DESTROY_SIGNALS; + flags |= (int) IOFlags::DESTROY_SIGNALS; return io_init(io, fmt, signals, flags); } @@ -138,7 +138,7 @@ int io_destroy(struct io *io) { int ret; - assert(io->state == STATE_CLOSED || io->state == STATE_INITIALIZED || io->state == STATE_CHECKED); + assert(io->state == State::CLOSED || io->state == State::INITIALIZED || io->state == State::CHECKED); ret = io_type(io)->destroy ? io_type(io)->destroy(io) : 0; if (ret) @@ -148,22 +148,22 @@ int io_destroy(struct io *io) free(io->in.buffer); free(io->out.buffer); - if (io->flags & IO_DESTROY_SIGNALS) { + if (io->flags & (int) IOFlags::DESTROY_SIGNALS) { ret = vlist_destroy(io->signals, (dtor_cb_t) signal_decref, false); if (ret) return ret; } - io->state = STATE_DESTROYED; + io->state = State::DESTROYED; return 0; } int io_check(struct io *io) { - assert(io->state != STATE_DESTROYED); + assert(io->state != State::DESTROYED); - io->state = STATE_CHECKED; + io->state = State::CHECKED; return 0; } @@ -177,7 +177,7 @@ int io_stream_open(struct io *io, const char *uri) goto stdio; } else if (aislocal(uri) == 1) { - io->mode = IO_MODE_STDIO; + io->mode = IOMode::STDIO; io->out.stream.std = fopen(uri, "a+"); if (io->out.stream.std == nullptr) @@ -188,7 +188,7 @@ int io_stream_open(struct io *io, const char *uri) return -1; } else { - io->mode = IO_MODE_ADVIO; + io->mode = IOMode::ADVIO; io->out.stream.adv = afopen(uri, "a+"); if (io->out.stream.adv == nullptr) @@ -200,15 +200,15 @@ int io_stream_open(struct io *io, const char *uri) } } else { -stdio: io->mode = IO_MODE_STDIO; - io->flags |= IO_FLUSH; +stdio: io->mode = IOMode::STDIO; + io->flags |= (int) IOFlags::FLUSH; io->in.stream.std = stdin; io->out.stream.std = stdout; } /* Make stream non-blocking if desired */ - if (io->flags & IO_NONBLOCK) { + if (io->flags & (int) IOFlags::NONBLOCK) { int ret, fd, flags; fd = io_fd(io); @@ -227,7 +227,7 @@ stdio: io->mode = IO_MODE_STDIO; } /* Enable line buffering on stdio */ - if (io->mode == IO_MODE_STDIO) { + if (io->mode == IOMode::STDIO) { ret = setvbuf(io->in.stream.std, nullptr, _IOLBF, BUFSIZ); if (ret) return -1; @@ -245,7 +245,7 @@ int io_stream_close(struct io *io) int ret; switch (io->mode) { - case IO_MODE_ADVIO: + case IOMode::ADVIO: ret = afclose(io->in.stream.adv); if (ret) return ret; @@ -256,7 +256,7 @@ int io_stream_close(struct io *io) return 0; - case IO_MODE_STDIO: + case IOMode::STDIO: if (io->in.stream.std == stdin) return 0; @@ -270,7 +270,7 @@ int io_stream_close(struct io *io) return 0; - case IO_MODE_CUSTOM: + case IOMode::CUSTOM: return 0; } @@ -280,11 +280,11 @@ int io_stream_close(struct io *io) int io_stream_flush(struct io *io) { switch (io->mode) { - case IO_MODE_ADVIO: + case IOMode::ADVIO: return afflush(io->out.stream.adv); - case IO_MODE_STDIO: + case IOMode::STDIO: return fflush(io->out.stream.std); - case IO_MODE_CUSTOM: + case IOMode::CUSTOM: return 0; } @@ -294,11 +294,11 @@ int io_stream_flush(struct io *io) int io_stream_eof(struct io *io) { switch (io->mode) { - case IO_MODE_ADVIO: + case IOMode::ADVIO: return afeof(io->in.stream.adv); - case IO_MODE_STDIO: + case IOMode::STDIO: return feof(io->in.stream.std); - case IO_MODE_CUSTOM: + case IOMode::CUSTOM: return 0; } @@ -308,24 +308,24 @@ int io_stream_eof(struct io *io) void io_stream_rewind(struct io *io) { switch (io->mode) { - case IO_MODE_ADVIO: + case IOMode::ADVIO: arewind(io->in.stream.adv); break; - case IO_MODE_STDIO: + case IOMode::STDIO: rewind(io->in.stream.std); break; - case IO_MODE_CUSTOM: { } + case IOMode::CUSTOM: { } } } int io_stream_fd(struct io *io) { switch (io->mode) { - case IO_MODE_ADVIO: + case IOMode::ADVIO: return afileno(io->in.stream.adv); - case IO_MODE_STDIO: + case IOMode::STDIO: return fileno(io->in.stream.std); - case IO_MODE_CUSTOM: + case IOMode::CUSTOM: return -1; } @@ -336,7 +336,7 @@ int io_open(struct io *io, const char *uri) { int ret; - assert(io->state == STATE_CHECKED || io->state == STATE_CLOSED); + assert(io->state == State::CHECKED || io->state == State::CLOSED); ret = io_type(io)->open ? io_type(io)->open(io, uri) @@ -345,7 +345,7 @@ int io_open(struct io *io, const char *uri) return ret; io->header_printed = false; - io->state = STATE_OPENED; + io->state = State::OPENED; return 0; } @@ -354,7 +354,7 @@ int io_close(struct io *io) { int ret; - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); io_footer(io); @@ -364,14 +364,14 @@ int io_close(struct io *io) if (ret) return ret; - io->state = STATE_CLOSED; + io->state = State::CLOSED; return 0; } int io_flush(struct io *io) { - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); return io_type(io)->flush ? io_type(io)->flush(io) @@ -380,7 +380,7 @@ int io_flush(struct io *io) int io_eof(struct io *io) { - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); return io_type(io)->eof ? io_type(io)->eof(io) @@ -389,7 +389,7 @@ int io_eof(struct io *io) void io_rewind(struct io *io) { - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); if (io_type(io)->rewind) io_type(io)->rewind(io); @@ -399,7 +399,7 @@ void io_rewind(struct io *io) int io_fd(struct io *io) { - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); return io_type(io)->fd ? io_type(io)->fd(io) @@ -413,7 +413,7 @@ const struct format_type * io_type(struct io *io) void io_header(struct io *io, const struct sample *smp) { - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); if (io_type(io)->header) io_type(io)->header(io, smp); @@ -423,7 +423,7 @@ void io_header(struct io *io, const struct sample *smp) void io_footer(struct io *io) { - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); if (io_type(io)->footer) io_type(io)->footer(io); @@ -433,12 +433,12 @@ int io_print(struct io *io, struct sample *smps[], unsigned cnt) { int ret; - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); if (!io->header_printed && cnt > 0) io_header(io, smps[0]); - if (io->flags & IO_NEWLINES) + if (io->flags & (int) IOFlags::NEWLINES) ret = io_print_lines(io, smps, cnt); else if (io_type(io)->print) ret = io_type(io)->print(io, smps, cnt); @@ -453,7 +453,7 @@ int io_print(struct io *io, struct sample *smps[], unsigned cnt) else ret = -1; - if (io->flags & IO_FLUSH) + if (io->flags & (int) IOFlags::FLUSH) io_flush(io); return ret; @@ -463,9 +463,9 @@ int io_scan(struct io *io, struct sample *smps[], unsigned cnt) { int ret; - assert(io->state == STATE_OPENED); + assert(io->state == State::OPENED); - if (io->flags & IO_NEWLINES) + if (io->flags & (int) IOFlags::NEWLINES) ret = io_scan_lines(io, smps, cnt); else if (io_type(io)->scan) ret = io_type(io)->scan(io, smps, cnt); @@ -484,33 +484,33 @@ int io_scan(struct io *io, struct sample *smps[], unsigned cnt) } FILE * io_stream_output(struct io *io) { - if (io->state != STATE_OPENED) + if (io->state != State::OPENED) return 0; - return io->mode == IO_MODE_ADVIO + return io->mode == IOMode::ADVIO ? io->out.stream.adv->file : io->out.stream.std; } FILE * io_stream_input(struct io *io) { - if (io->state != STATE_OPENED) + if (io->state != State::OPENED) return 0; - return io->mode == IO_MODE_ADVIO + return io->mode == IOMode::ADVIO ? io->in.stream.adv->file : io->in.stream.std; } int io_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt) { - assert(io->state == STATE_CHECKED || io->state == STATE_OPENED); + assert(io->state == State::CHECKED || io->state == State::OPENED); return io_type(io)->sscan ? io_type(io)->sscan(io, buf, len, rbytes, smps, cnt) : -1; } int io_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt) { - assert(io->state == STATE_CHECKED || io->state == STATE_OPENED); + assert(io->state == State::CHECKED || io->state == State::OPENED); return io_type(io)->sprint ? io_type(io)->sprint(io, buf, len, wbytes, smps, cnt) : -1; } diff --git a/lib/mapping.cpp b/lib/mapping.cpp index 8e00a251f..fc2e167a9 100644 --- a/lib/mapping.cpp +++ b/lib/mapping.cpp @@ -66,7 +66,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n } if (!strcmp(type, "stats")) { - me->type = MAPPING_TYPE_STATS; + me->type = MappingType::STATS; me->length = 1; char *metric = strtok_r(nullptr, ".", &lasts); @@ -81,7 +81,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n me->stats.type = Stats::lookupType(type); } else if (!strcmp(type, "hdr")) { - me->type = MAPPING_TYPE_HEADER; + me->type = MappingType::HEADER; me->length = 1; field = strtok_r(nullptr, ".", &lasts); @@ -91,16 +91,16 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n } if (!strcmp(field, "sequence")) - me->header.type = MAPPING_HEADER_TYPE_SEQUENCE; + me->header.type = MappingHeaderType::SEQUENCE; else if (!strcmp(field, "length")) - me->header.type = MAPPING_HEADER_TYPE_LENGTH; + me->header.type = MappingHeaderType::LENGTH; else { warning("Invalid header type"); goto invalid_format; } } else if (!strcmp(type, "ts")) { - me->type = MAPPING_TYPE_TIMESTAMP; + me->type = MappingType::TIMESTAMP; me->length = 2; field = strtok_r(nullptr, ".", &lasts); @@ -110,9 +110,9 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n } if (!strcmp(field, "origin")) - me->timestamp.type = MAPPING_TIMESTAMP_TYPE_ORIGIN; + me->timestamp.type = MappingTimestampType::ORIGIN; else if (!strcmp(field, "received")) - me->timestamp.type = MAPPING_TIMESTAMP_TYPE_RECEIVED; + me->timestamp.type = MappingTimestampType::RECEIVED; else { warning("Invalid timestamp type"); goto invalid_format; @@ -122,7 +122,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n char *first_str, *last_str; int first = -1, last = -1; - me->type = MAPPING_TYPE_DATA; + me->type = MappingType::DATA; first_str = strtok_r(nullptr, "-]", &lasts); if (first_str) { @@ -240,18 +240,18 @@ int mapping_update(const struct mapping_entry *me, struct sample *remapped, cons return -1; switch (me->type) { - case MAPPING_TYPE_STATS: + case MappingType::STATS: remapped->data[me->offset] = me->node->stats->getValue(me->stats.metric, me->stats.type); break; - case MAPPING_TYPE_TIMESTAMP: { + case MappingType::TIMESTAMP: { const struct timespec *ts; switch (me->timestamp.type) { - case MAPPING_TIMESTAMP_TYPE_RECEIVED: + case MappingTimestampType::RECEIVED: ts = &original->ts.received; break; - case MAPPING_TIMESTAMP_TYPE_ORIGIN: + case MappingTimestampType::ORIGIN: ts = &original->ts.origin; break; default: @@ -263,13 +263,13 @@ int mapping_update(const struct mapping_entry *me, struct sample *remapped, cons break; } - case MAPPING_TYPE_HEADER: + case MappingType::HEADER: switch (me->header.type) { - case MAPPING_HEADER_TYPE_LENGTH: + case MappingHeaderType::LENGTH: remapped->data[me->offset].i = original->length; break; - case MAPPING_HEADER_TYPE_SEQUENCE: + case MappingHeaderType::SEQUENCE: remapped->data[me->offset].i = original->sequence; break; @@ -278,7 +278,7 @@ int mapping_update(const struct mapping_entry *me, struct sample *remapped, cons } break; - case MAPPING_TYPE_DATA: + case MappingType::DATA: for (unsigned j = me->data.offset, i = me->offset; j < MIN(original->length, (unsigned) (me->data.offset + me->length)); @@ -322,7 +322,7 @@ int mapping_list_prepare(struct vlist *ml) struct mapping_entry *me = (struct mapping_entry *) vlist_at(ml, i); if (me->length < 0) { - struct vlist *sigs = node_get_signals(me->node, NODE_DIR_IN); + struct vlist *sigs = node_get_signals(me->node, NodeDir::IN); me->length = vlist_length(sigs); } @@ -344,20 +344,20 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str) strcatf(str, "%s.", node_name_short(me->node)); switch (me->type) { - case MAPPING_TYPE_STATS: + case MappingType::STATS: strcatf(str, "stats.%s.%s", Stats::metrics[me->stats.metric].name, Stats::types[me->stats.type].name ); break; - case MAPPING_TYPE_HEADER: + case MappingType::HEADER: switch (me->header.type) { - case MAPPING_HEADER_TYPE_LENGTH: + case MappingHeaderType::LENGTH: type = "length"; break; - case MAPPING_HEADER_TYPE_SEQUENCE: + case MappingHeaderType::SEQUENCE: type = "sequence"; break; @@ -368,13 +368,13 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str) strcatf(str, "hdr.%s", type); break; - case MAPPING_TYPE_TIMESTAMP: + case MappingType::TIMESTAMP: switch (me->timestamp.type) { - case MAPPING_TIMESTAMP_TYPE_ORIGIN: + case MappingTimestampType::ORIGIN: type = "origin"; break; - case MAPPING_TIMESTAMP_TYPE_RECEIVED: + case MappingTimestampType::RECEIVED: type = "received"; break; @@ -385,7 +385,7 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str) strcatf(str, "ts.%s.%s", type, index == 0 ? "sec" : "nsec"); break; - case MAPPING_TYPE_DATA: + case MappingType::DATA: if (me->node && index < vlist_length(&me->node->in.signals)) { struct signal *s = (struct signal *) vlist_at(&me->node->in.signals, index); diff --git a/lib/memory.cpp b/lib/memory.cpp index 196cbfcc4..a5a3eb0fe 100644 --- a/lib/memory.cpp +++ b/lib/memory.cpp @@ -156,11 +156,11 @@ struct memory_allocation * memory_get_allocation(void *ptr) return allocations[ptr]; } -struct memory_type * memory_type_lookup(enum memory_type_flags flags) +struct memory_type * memory_type_lookup(enum MemoryFlags flags) { - if (flags & MEMORY_HUGEPAGE) + if ((int) flags & (int) MemoryFlags::HUGEPAGE) return &memory_hugepage; - else if (flags & MEMORY_HEAP) + else if ((int) flags & (int) MemoryFlags::HEAP) return &memory_heap; else return nullptr; diff --git a/lib/memory/heap.cpp b/lib/memory/heap.cpp index e3085c4a5..e718aea6c 100644 --- a/lib/memory/heap.cpp +++ b/lib/memory/heap.cpp @@ -61,7 +61,7 @@ static int memory_heap_free(struct memory_type *m, struct memory_allocation *ma) /* List of available memory types */ struct memory_type memory_heap = { .name = "heap", - .flags = MEMORY_HEAP, + .flags = (int) MemoryFlags::HEAP, .alignment = 1, .alloc = memory_heap_alloc, .free = memory_heap_free diff --git a/lib/memory/hugepage.cpp b/lib/memory/hugepage.cpp index 64fbfe81e..b460e266c 100644 --- a/lib/memory/hugepage.cpp +++ b/lib/memory/hugepage.cpp @@ -146,7 +146,7 @@ static int memory_hugepage_free(struct memory_type *m, struct memory_allocation struct memory_type memory_hugepage = { .name = "mmap_hugepages", - .flags = MEMORY_MMAP | MEMORY_HUGEPAGE, + .flags = (int) MemoryFlags::MMAP | (int) MemoryFlags::HUGEPAGE, .alignment = 21, /* 2 MiB hugepage */ .alloc = memory_hugepage_alloc, .free = memory_hugepage_free diff --git a/lib/node.cpp b/lib/node.cpp index 7b78e007c..edb4ac922 100644 --- a/lib/node.cpp +++ b/lib/node.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -49,7 +49,7 @@ using namespace villas::utils; int node_init(struct node *n, struct node_type *vt) { int ret; - assert(n->state == STATE_DESTROYED); + assert(n->state == State::DESTROYED); n->_vt = vt; n->_vd = alloc(vt->size); @@ -70,11 +70,11 @@ int node_init(struct node *n, struct node_type *vt) #endif /* WITH_NETEM */ /* Default values */ - ret = node_direction_init(&n->in, NODE_DIR_IN, n); + ret = node_direction_init(&n->in, NodeDir::IN, n); if (ret) return ret; - ret = node_direction_init(&n->out, NODE_DIR_OUT, n); + ret = node_direction_init(&n->out, NodeDir::OUT, n); if (ret) return ret; @@ -82,7 +82,7 @@ int node_init(struct node *n, struct node_type *vt) if (ret) return ret; - n->state = STATE_INITIALIZED; + n->state = State::INITIALIZED; vlist_push(&vt->instances, n); @@ -93,7 +93,7 @@ int node_prepare(struct node *n) { int ret; - assert(n->state == STATE_CHECKED); + assert(n->state == State::CHECKED); ret = node_type(n)->prepare ? node_type(n)->prepare(n) : 0; if (ret) @@ -107,7 +107,7 @@ int node_prepare(struct node *n) if (ret) return ret; - n->state = STATE_PREPARED; + n->state = State::PREPARED; return 0; } @@ -197,7 +197,7 @@ int node_parse(struct node *n, json_t *json, const char *name) return ret; n->cfg = json; - n->state = STATE_PARSED; + n->state = State::PARSED; return 0; } @@ -205,7 +205,7 @@ int node_parse(struct node *n, json_t *json, const char *name) int node_check(struct node *n) { int ret; - assert(n->state != STATE_DESTROYED); + assert(n->state != State::DESTROYED); ret = node_direction_check(&n->in, n); if (ret) @@ -219,7 +219,7 @@ int node_check(struct node *n) if (ret) return ret; - n->state = STATE_CHECKED; + n->state = State::CHECKED; return 0; } @@ -228,8 +228,8 @@ int node_start(struct node *n) { int ret; - assert(n->state == STATE_PREPARED); - assert(node_type(n)->state == STATE_STARTED); + assert(n->state == State::PREPARED); + assert(node_type(n)->state == State::STARTED); info("Starting node %s", node_name_long(n)); @@ -263,7 +263,7 @@ int node_start(struct node *n) } #endif /* __linux__ */ - n->state = STATE_STARTED; + n->state = State::STARTED; n->sequence = 0; return ret; @@ -273,7 +273,7 @@ int node_stop(struct node *n) { int ret; - if (n->state != STATE_STOPPING && n->state != STATE_STARTED && n->state != STATE_CONNECTED && n->state != STATE_PENDING_CONNECT) + if (n->state != State::STOPPING && n->state != State::STARTED && n->state != State::CONNECTED && n->state != State::PENDING_CONNECT) return 0; info("Stopping node %s", node_name(n)); @@ -289,7 +289,7 @@ int node_stop(struct node *n) ret = node_type(n)->stop ? node_type(n)->stop(n) : 0; if (ret == 0) - n->state = STATE_STOPPED; + n->state = State::STOPPED; return ret; } @@ -298,7 +298,7 @@ int node_pause(struct node *n) { int ret; - if (n->state != STATE_STARTED) + if (n->state != State::STARTED) return -1; info("Pausing node %s", node_name(n)); @@ -306,7 +306,7 @@ int node_pause(struct node *n) ret = node_type(n)->pause ? node_type(n)->pause(n) : 0; if (ret == 0) - n->state = STATE_PAUSED; + n->state = State::PAUSED; return ret; } @@ -315,7 +315,7 @@ int node_resume(struct node *n) { int ret; - if (n->state != STATE_PAUSED) + if (n->state != State::PAUSED) return -1; info("Resuming node %s", node_name(n)); @@ -323,7 +323,7 @@ int node_resume(struct node *n) ret = node_type(n)->resume ? node_type(n)->resume(n) : 0; if (ret == 0) - n->state = STATE_STARTED; + n->state = State::STARTED; return ret; } @@ -332,7 +332,7 @@ int node_restart(struct node *n) { int ret; - if (n->state != STATE_STARTED) + if (n->state != State::STARTED) return -1; info("Restarting node %s", node_name(n)); @@ -355,7 +355,7 @@ int node_restart(struct node *n) int node_destroy(struct node *n) { int ret; - assert(n->state != STATE_DESTROYED && n->state != STATE_STARTED); + assert(n->state != State::DESTROYED && n->state != State::STARTED); ret = node_direction_destroy(&n->in, n); if (ret) @@ -390,7 +390,7 @@ int node_destroy(struct node *n) rtnl_cls_put(n->tc_classifier); #endif /* WITH_NETEM */ - n->state = STATE_DESTROYED; + n->state = State::DESTROYED; return 0; } @@ -401,9 +401,9 @@ int node_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *rel assert(node_type(n)->read); - if (n->state == STATE_PAUSED || n->state == STATE_PENDING_CONNECT) + if (n->state == State::PAUSED || n->state == State::PENDING_CONNECT) return 0; - else if (n->state != STATE_STARTED && n->state != STATE_CONNECTED) + else if (n->state != State::STARTED && n->state != State::CONNECTED) return -1; /* Send in parts if vector not supported */ @@ -447,9 +447,9 @@ int node_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *re assert(node_type(n)->write); - if (n->state == STATE_PAUSED || n->state == STATE_PENDING_CONNECT) + if (n->state == State::PAUSED || n->state == State::PENDING_CONNECT) return 0; - else if (n->state != STATE_STARTED && n->state != STATE_CONNECTED) + else if (n->state != State::STARTED && n->state != State::CONNECTED) return -1; #ifdef WITH_HOOKS @@ -619,9 +619,9 @@ bool node_is_enabled(const struct node *n) return n->enabled; } -struct vlist * node_get_signals(struct node *n, enum node_dir dir) +struct vlist * node_get_signals(struct node *n, enum NodeDir dir) { - struct node_direction *nd = dir == NODE_DIR_IN ? &n->in : &n->out; + struct node_direction *nd = dir == NodeDir::IN ? &n->in : &n->out; return node_direction_get_signals(nd); } diff --git a/lib/node_direction.cpp b/lib/node_direction.cpp index 130d12f8c..2875c9cf8 100644 --- a/lib/node_direction.cpp +++ b/lib/node_direction.cpp @@ -23,42 +23,43 @@ #include #include -#include +#include #include #include #include +using namespace villas::node; using namespace villas::utils; int node_direction_prepare(struct node_direction *nd, struct node *n) { - assert(nd->state == STATE_CHECKED); + assert(nd->state == State::CHECKED); #ifdef WITH_HOOKS - int t = nd->direction == NODE_DIR_OUT ? HOOK_NODE_WRITE : HOOK_NODE_READ; - int m = nd->builtin ? t | HOOK_BUILTIN : 0; + int t = nd->direction == NodeDir::OUT ? (int) Hook::Flags::NODE_WRITE : (int) Hook::Flags::NODE_READ; + int m = nd->builtin ? t | (int) Hook::Flags::BUILTIN : 0; hook_list_prepare(&nd->hooks, &nd->signals, m, nullptr, n); #endif /* WITH_HOOKS */ - nd->state = STATE_PREPARED; + nd->state = State::PREPARED; return 0; } -int node_direction_init(struct node_direction *nd, enum node_dir dir, struct node *n) +int node_direction_init(struct node_direction *nd, enum NodeDir dir, struct node *n) { int ret; - assert(nd->state == STATE_DESTROYED); + assert(nd->state == State::DESTROYED); nd->direction = dir; nd->enabled = 1; nd->vectorize = 1; nd->builtin = 1; - nd->hooks.state = STATE_DESTROYED; - nd->signals.state = STATE_DESTROYED; + nd->hooks.state = State::DESTROYED; + nd->signals.state = State::DESTROYED; #ifdef WITH_HOOKS ret = hook_list_init(&nd->hooks); @@ -70,7 +71,7 @@ int node_direction_init(struct node_direction *nd, enum node_dir dir, struct nod if (ret) return ret; - nd->state = STATE_INITIALIZED; + nd->state = State::INITIALIZED; return 0; } @@ -79,7 +80,7 @@ int node_direction_destroy(struct node_direction *nd, struct node *n) { int ret = 0; - assert(nd->state != STATE_DESTROYED && nd->state != STATE_STARTED); + assert(nd->state != State::DESTROYED && nd->state != State::STARTED); #ifdef WITH_HOOKS ret = hook_list_destroy(&nd->hooks); @@ -91,7 +92,7 @@ int node_direction_destroy(struct node_direction *nd, struct node *n) if (ret) return ret; - nd->state = STATE_DESTROYED; + nd->state = State::DESTROYED; return 0; } @@ -100,7 +101,7 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg) { int ret; - assert(nd->state == STATE_INITIALIZED); + assert(nd->state == State::INITIALIZED); json_error_t err; json_t *json_hooks = nullptr; @@ -118,7 +119,7 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg) if (ret) jerror(&err, "Failed to parse node %s", node_name(n)); - if (n->_vt->flags & NODE_TYPE_PROVIDES_SIGNALS) { + if (n->_vt->flags & (int) NodeFlags::PROVIDES_SIGNALS) { if (json_signals) error("Node %s does not support signal definitions", node_name(n)); } @@ -145,8 +146,8 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg) ); } - enum signal_type type = signal_type_from_str(type_str); - if (type == SIGNAL_TYPE_INVALID) + enum SignalType type = signal_type_from_str(type_str); + if (type == SignalType::INVALID) error("Invalid signal type %s", type_str); ret = signal_list_generate(&nd->signals, count, type); @@ -156,20 +157,20 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg) #ifdef WITH_HOOKS if (json_hooks) { - int m = nd->direction == NODE_DIR_OUT ? HOOK_NODE_WRITE : HOOK_NODE_READ; + int m = nd->direction == NodeDir::OUT ? (int) Hook::Flags::NODE_WRITE : (int) Hook::Flags::NODE_READ; hook_list_parse(&nd->hooks, json_hooks, m, nullptr, n); } #endif /* WITH_HOOKS */ - nd->state = STATE_PARSED; + nd->state = State::PARSED; return 0; } int node_direction_check(struct node_direction *nd, struct node *n) { - assert(nd->state == STATE_PARSED); + assert(nd->state == State::PARSED); if (nd->vectorize <= 0) error("Invalid setting 'vectorize' with value %d for node %s. Must be natural number!", nd->vectorize, node_name(n)); @@ -178,40 +179,40 @@ int node_direction_check(struct node_direction *nd, struct node *n) error("Invalid value for setting 'vectorize'. Node type requires a number smaller than %d!", node_type(n)->vectorize); - nd->state = STATE_CHECKED; + nd->state = State::CHECKED; return 0; } int node_direction_start(struct node_direction *nd, struct node *n) { - assert(nd->state == STATE_PREPARED); + assert(nd->state == State::PREPARED); #ifdef WITH_HOOKS hook_list_start(&nd->hooks); #endif /* WITH_HOOKS */ - nd->state = STATE_STARTED; + nd->state = State::STARTED; return 0; } int node_direction_stop(struct node_direction *nd, struct node *n) { - assert(nd->state == STATE_STARTED); + assert(nd->state == State::STARTED); #ifdef WITH_HOOKS hook_list_stop(&nd->hooks); #endif /* WITH_HOOKS */ - nd->state = STATE_STOPPED; + nd->state = State::STOPPED; return 0; } struct vlist * node_direction_get_signals(struct node_direction *nd) { - assert(nd->state == STATE_PREPARED); + assert(nd->state == State::PREPARED); #ifdef WITH_HOOKS if (vlist_length(&nd->hooks) > 0) diff --git a/lib/node_type.cpp b/lib/node_type.cpp index 6de9800cc..d8c20a00d 100644 --- a/lib/node_type.cpp +++ b/lib/node_type.cpp @@ -33,14 +33,14 @@ int node_type_start(struct node_type *vt, villas::node::SuperNode *sn) { int ret; - if (vt->state != STATE_DESTROYED) + if (vt->state != State::DESTROYED) return 0; info("Initializing " CLR_YEL("%s") " node type which is used by %zu nodes", node_type_name(vt), vlist_length(&vt->instances)); ret = vt->type.start ? vt->type.start(sn) : 0; if (ret == 0) - vt->state = STATE_STARTED; + vt->state = State::STARTED; return ret; } @@ -49,14 +49,14 @@ int node_type_stop(struct node_type *vt) { int ret; - if (vt->state != STATE_STARTED) + if (vt->state != State::STARTED) return 0; info("De-initializing " CLR_YEL("%s") " node type", node_type_name(vt)); ret = vt->type.stop ? vt->type.stop() : 0; if (ret == 0) - vt->state = STATE_DESTROYED; + vt->state = State::DESTROYED; return ret; } @@ -70,7 +70,7 @@ struct node_type * node_type_lookup(const char *name) { struct plugin *p; - p = plugin_lookup(PLUGIN_TYPE_NODE, name); + p = plugin_lookup(PluginType::NODE, name); if (!p) return nullptr; diff --git a/lib/nodes/amqp.cpp b/lib/nodes/amqp.cpp index 18f255213..a99776266 100644 --- a/lib/nodes/amqp.cpp +++ b/lib/nodes/amqp.cpp @@ -241,7 +241,7 @@ int amqp_start(struct node *n) amqp_rpc_reply_t rep; amqp_queue_declare_ok_t *r; - ret = io_init(&a->io, a->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&a->io, a->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -398,13 +398,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "amqp"; p.description = "Advanced Message Queueing Protoocl (rabbitmq-c)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct amqp); p.node.destroy = amqp_destroy; @@ -422,7 +422,7 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/comedi.cpp b/lib/nodes/comedi.cpp index 8ecb0c815..b6ecf293d 100644 --- a/lib/nodes/comedi.cpp +++ b/lib/nodes/comedi.cpp @@ -573,7 +573,7 @@ int comedi_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r for (size_t i = 0; i < cnt; i++) { d->counter++; - smps[i]->flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_DATA | SAMPLE_HAS_SEQUENCE; + smps[i]->flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_SEQUENCE; smps[i]->sequence = d->counter / d->chanlist_len; struct timespec offset = time_from_double(d->counter * 1.0 / d->sample_rate_hz); @@ -718,7 +718,7 @@ int comedi_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r for (size_t i = 0; i < cnt; i++) { d->counter++; - smps[i]->flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_DATA | SAMPLE_HAS_SEQUENCE; + smps[i]->flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_SEQUENCE; smps[i]->sequence = d->counter / d->chanlist_len; struct timespec offset = time_from_double(d->counter * 1.0 / d->sample_rate_hz); @@ -880,25 +880,25 @@ int comedi_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned * unsigned raw_value = 0; switch (sample_format(sample, si)) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: raw_value = comedi_from_phys(sample->data[si].f, d->chanspecs[si].range, d->chanspecs[si].maxdata); break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: /* Treat sample as already raw DAC value */ raw_value = sample->data[si].i; break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: raw_value = comedi_from_phys(sample->data[si].b ? 1 : 0, d->chanspecs[si].range, d->chanspecs[si].maxdata); break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: /* We only output the real part */ raw_value = comedi_from_phys(creal(sample->data[si].z), d->chanspecs[si].range, d->chanspecs[si].maxdata); break; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: raw_value = 0; break; } @@ -992,13 +992,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "comedi"; p.description = "Comedi-compatible DAQ/ADC cards"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct comedi); p.node.parse = comedi_parse; @@ -1015,6 +1015,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index dea9ec1fa..6400e2d81 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -107,7 +107,7 @@ int exec_parse(struct node *n, json_t *cfg) throw ConfigError(json_format, "node-config-node-exec-format", "Invalid format: {)", format); } - if (!(e->format->flags & IO_NEWLINES)) { + if (!(e->format->flags & (int) IOFlags::NEWLINES)) { json_t *json_format = json_object_get(cfg, "format"); throw ConfigError(json_format, "node-config-node-exec-format", "Only line-delimited formats are currently supported"); } @@ -121,7 +121,7 @@ int exec_prepare(struct node *n) struct exec *e = (struct exec *) n->_vd; /* Initialize IO */ - ret = io_init(&e->io, e->format, &n->in.signals, SAMPLE_HAS_ALL); + ret = io_init(&e->io, e->format, &n->in.signals, (int) SampleFlags::HAS_ALL); if (ret) return ret; @@ -236,13 +236,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "exec"; p.description = "run subprocesses with stdin/stdout communication"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct exec); p.node.parse = exec_parse; @@ -261,6 +261,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/file.cpp b/lib/nodes/file.cpp index 403e98d9c..8d2961f10 100644 --- a/lib/nodes/file.cpp +++ b/lib/nodes/file.cpp @@ -49,7 +49,7 @@ static char * file_format_name(const char *format, struct timespec *ts) return buf; } -static struct timespec file_calc_offset(const struct timespec *first, const struct timespec *epoch, enum file::epoch mode) +static struct timespec file_calc_offset(const struct timespec *first, const struct timespec *epoch, enum file::EpochMode mode) { /* Get current time */ struct timespec now = time_now(); @@ -57,18 +57,18 @@ static struct timespec file_calc_offset(const struct timespec *first, const stru /* Set offset depending on epoch */ switch (mode) { - case file::epoch::DIRECT: /* read first value at now + epoch */ + case file::EpochMode::DIRECT: /* read first value at now + epoch */ offset = time_diff(first, &now); return time_add(&offset, epoch); - case file::epoch::WAIT: /* read first value at now + first + epoch */ + case file::EpochMode::WAIT: /* read first value at now + first + epoch */ offset = now; return time_add(&now, epoch); - case file::epoch::RELATIVE: /* read first value at first + epoch */ + case file::EpochMode::RELATIVE: /* read first value at first + epoch */ return *epoch; - case file::epoch::ABSOLUTE: /* read first value at f->epoch */ + case file::EpochMode::ABSOLUTE: /* read first value at f->epoch */ return time_diff(first, epoch); default: @@ -91,8 +91,8 @@ int file_parse(struct node *n, json_t *cfg) /* Default values */ f->rate = 0; - f->eof_mode = file::eof::STOP; - f->epoch_mode = file::epoch::DIRECT; + f->eof_mode = file::EOFBehaviour::STOP; + f->epoch_mode = file::EpochMode::DIRECT; f->flush = 0; f->buffer_size_in = 0; f->buffer_size_out = 0; @@ -122,26 +122,26 @@ int file_parse(struct node *n, json_t *cfg) if (eof) { if (!strcmp(eof, "exit") || !strcmp(eof, "stop")) - f->eof_mode = file::eof::STOP; + f->eof_mode = file::EOFBehaviour::STOP; else if (!strcmp(eof, "rewind")) - f->eof_mode = file::eof::REWIND; + f->eof_mode = file::EOFBehaviour::REWIND; else if (!strcmp(eof, "wait")) - f->eof_mode = file::eof::SUSPEND; + f->eof_mode = file::EOFBehaviour::SUSPEND; else error("Invalid mode '%s' for 'eof' setting of node %s", eof, node_name(n)); } if (epoch) { if (!strcmp(epoch, "direct")) - f->epoch_mode = file::epoch::DIRECT; + f->epoch_mode = file::EpochMode::DIRECT; else if (!strcmp(epoch, "wait")) - f->epoch_mode = file::epoch::WAIT; + f->epoch_mode = file::EpochMode::WAIT; else if (!strcmp(epoch, "relative")) - f->epoch_mode = file::epoch::RELATIVE; + f->epoch_mode = file::EpochMode::RELATIVE; else if (!strcmp(epoch, "absolute")) - f->epoch_mode = file::epoch::ABSOLUTE; + f->epoch_mode = file::EpochMode::ABSOLUTE; else if (!strcmp(epoch, "original")) - f->epoch_mode = file::epoch::ORIGINAL; + f->epoch_mode = file::EpochMode::ORIGINAL; else error("Invalid value '%s' for setting 'epoch' of node %s", epoch, node_name(n)); } @@ -160,23 +160,23 @@ char * file_print(struct node *n) const char *eof_str = nullptr; switch (f->epoch_mode) { - case file::epoch::DIRECT: + case file::EpochMode::DIRECT: epoch_str = "direct"; break; - case file::epoch::WAIT: + case file::EpochMode::WAIT: epoch_str = "wait"; break; - case file::epoch::RELATIVE: + case file::EpochMode::RELATIVE: epoch_str = "relative"; break; - case file::epoch::ABSOLUTE: + case file::EpochMode::ABSOLUTE: epoch_str = "absolute"; break; - case file::epoch::ORIGINAL: + case file::EpochMode::ORIGINAL: epoch_str = "original"; break; @@ -186,15 +186,15 @@ char * file_print(struct node *n) } switch (f->eof_mode) { - case file::eof::STOP: + case file::EOFBehaviour::STOP: eof_str = "stop"; break; - case file::eof::SUSPEND: + case file::EOFBehaviour::SUSPEND: eof_str = "wait"; break; - case file::eof::REWIND: + case file::EOFBehaviour::REWIND: eof_str = "rewind"; break; @@ -271,9 +271,9 @@ int file_start(struct node *n) } /* Open file */ - flags = SAMPLE_HAS_ALL; + flags = (int) SampleFlags::HAS_ALL; if (f->flush) - flags |= IO_FLUSH; + flags |= (int) IOFlags::FLUSH; ret = io_init(&f->io, f->format, &n->in.signals, flags); if (ret) @@ -305,7 +305,7 @@ int file_start(struct node *n) serror("Failed to create timer"); /* Get timestamp of first line */ - if (f->epoch_mode != file::epoch::ORIGINAL) { + if (f->epoch_mode != file::EpochMode::ORIGINAL) { io_rewind(&f->io); if (io_eof(&f->io)) { @@ -376,37 +376,37 @@ retry: ret = io_scan(&f->io, smps, cnt); if (ret <= 0) { if (io_eof(&f->io)) { switch (f->eof_mode) { - case file::eof::REWIND: + case file::EOFBehaviour::REWIND: info("Rewind input file of node %s", node_name(n)); f->offset = file_calc_offset(&f->first, &f->epoch, f->epoch_mode); io_rewind(&f->io); goto retry; - case file::eof::SUSPEND: + case file::EOFBehaviour::SUSPEND: /* We wait 10ms before fetching again. */ usleep(100000); /* Try to download more data if this is a remote file. */ switch (f->io.mode) { - case IO_MODE_ADVIO: + case IOMode::ADVIO: adownload(f->io.in.stream.adv, 1); break; - case IO_MODE_STDIO: + case IOMode::STDIO: clearerr(f->io.in.stream.std); break; - case IO_MODE_CUSTOM: + case IOMode::CUSTOM: break; } goto retry; - case file::eof::STOP: + case file::EOFBehaviour::STOP: info("Reached end-of-file."); - n->state = STATE_STOPPING; + n->state = State::STOPPING; return -1; @@ -420,7 +420,7 @@ retry: ret = io_scan(&f->io, smps, cnt); } /* We dont wait in FILE_EPOCH_ORIGINAL mode */ - if (f->epoch_mode == file::epoch::ORIGINAL) + if (f->epoch_mode == file::EpochMode::ORIGINAL) return cnt; if (f->rate) { @@ -467,7 +467,7 @@ int file_poll_fds(struct node *n, int fds[]) return 1; } - else if (f->epoch_mode == file::epoch::ORIGINAL) { + else if (f->epoch_mode == file::EpochMode::ORIGINAL) { fds[0] = io_fd(&f->io); return 1; @@ -480,13 +480,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "file"; p.description = "support for file log / replay node type"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 1; p.node.size = sizeof(struct file); p.node.parse = file_parse; @@ -504,6 +504,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/iec61850.cpp b/lib/nodes/iec61850.cpp index 631153d60..7b0c8a1ad 100644 --- a/lib/nodes/iec61850.cpp +++ b/lib/nodes/iec61850.cpp @@ -39,26 +39,26 @@ using namespace villas::utils; const struct iec61850_type_descriptor type_descriptors[] = { /* name, iec_type, type, size, supported */ - { "boolean", iec61850_type::BOOLEAN, SIGNAL_TYPE_BOOLEAN, 1, false, false }, - { "int8", iec61850_type::INT8, SIGNAL_TYPE_INTEGER, 1, false, false }, - { "int16", iec61850_type::INT16, SIGNAL_TYPE_INTEGER, 2, false, false }, - { "int32", iec61850_type::INT32, SIGNAL_TYPE_INTEGER, 4, false, false }, - { "int64", iec61850_type::INT64, SIGNAL_TYPE_INTEGER, 8, false, false }, - { "int8u", iec61850_type::INT8U, SIGNAL_TYPE_INTEGER, 1, false, false }, - { "int16u", iec61850_type::INT16U, SIGNAL_TYPE_INTEGER, 2, false, false }, - { "int32u", iec61850_type::INT32U, SIGNAL_TYPE_INTEGER, 4, false, false }, - { "int64u", iec61850_type::INT64U, SIGNAL_TYPE_INTEGER, 8, false, false }, - { "float32", iec61850_type::FLOAT32, SIGNAL_TYPE_FLOAT, 4, false, false }, - { "float64", iec61850_type::FLOAT64, SIGNAL_TYPE_FLOAT, 8, false, false }, - { "enumerated", iec61850_type::ENUMERATED, SIGNAL_TYPE_INVALID, 4, false, false }, - { "coded_enum", iec61850_type::CODED_ENUM, SIGNAL_TYPE_INVALID, 4, false, false }, - { "octet_string", iec61850_type::OCTET_STRING, SIGNAL_TYPE_INVALID, 20, false, false }, - { "visible_string", iec61850_type::VISIBLE_STRING, SIGNAL_TYPE_INVALID, 35, false, false }, - { "objectname", iec61850_type::OBJECTNAME, SIGNAL_TYPE_INVALID, 20, false, false }, - { "objectreference", iec61850_type::OBJECTREFERENCE, SIGNAL_TYPE_INVALID, 20, false, false }, - { "timestamp", iec61850_type::TIMESTAMP, SIGNAL_TYPE_INVALID, 8, false, false }, - { "entrytime", iec61850_type::ENTRYTIME, SIGNAL_TYPE_INVALID, 6, false, false }, - { "bitstring", iec61850_type::BITSTRING, SIGNAL_TYPE_INVALID, 4, false, false } + { "boolean", IEC61850Type::BOOLEAN, SignalType::BOOLEAN, 1, false, false }, + { "int8", IEC61850Type::INT8, SignalType::INTEGER, 1, false, false }, + { "int16", IEC61850Type::INT16, SignalType::INTEGER, 2, false, false }, + { "int32", IEC61850Type::INT32, SignalType::INTEGER, 4, false, false }, + { "int64", IEC61850Type::INT64, SignalType::INTEGER, 8, false, false }, + { "int8u", IEC61850Type::INT8U, SignalType::INTEGER, 1, false, false }, + { "int16u", IEC61850Type::INT16U, SignalType::INTEGER, 2, false, false }, + { "int32u", IEC61850Type::INT32U, SignalType::INTEGER, 4, false, false }, + { "int64u", IEC61850Type::INT64U, SignalType::INTEGER, 8, false, false }, + { "float32", IEC61850Type::FLOAT32, SignalType::FLOAT, 4, false, false }, + { "float64", IEC61850Type::FLOAT64, SignalType::FLOAT, 8, false, false }, + { "enumerated", IEC61850Type::ENUMERATED, SignalType::INVALID, 4, false, false }, + { "coded_enum", IEC61850Type::CODED_ENUM, SignalType::INVALID, 4, false, false }, + { "octet_string", IEC61850Type::OCTET_STRING, SignalType::INVALID, 20, false, false }, + { "visible_string", IEC61850Type::VISIBLE_STRING, SignalType::INVALID, 35, false, false }, + { "objectname", IEC61850Type::OBJECTNAME, SignalType::INVALID, 20, false, false }, + { "objectreference", IEC61850Type::OBJECTREFERENCE, SignalType::INVALID, 20, false, false }, + { "timestamp", IEC61850Type::TIMESTAMP, SignalType::INVALID, 8, false, false }, + { "entrytime", IEC61850Type::ENTRYTIME, SignalType::INVALID, 6, false, false }, + { "bitstring", IEC61850Type::BITSTRING, SignalType::INVALID, 4, false, false } }; /** Each network interface needs a separate receiver */ @@ -80,8 +80,8 @@ static void * iec61850_thread(void *ctx) struct iec61850_receiver *r = (struct iec61850_receiver *) vlist_at(&receivers, i); switch (r->type) { - case iec61850_receiver::type::GOOSE: GooseReceiver_tick(r->goose); break; - case iec61850_receiver::type::SAMPLED_VALUES: SVReceiver_tick(r->sv); break; + case iec61850_receiver::Type::GOOSE: GooseReceiver_tick(r->goose); break; + case iec61850_receiver::Type::SAMPLED_VALUES: SVReceiver_tick(r->sv); break; } } } @@ -129,15 +129,15 @@ int iec61850_parse_signals(json_t *json_signals, struct vlist *signals, struct v return -1; switch (sig->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: iec_type = "boolean"; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: iec_type = "float64"; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: iec_type = "int64"; break; @@ -226,11 +226,11 @@ int iec61850_type_stop() int iec61850_receiver_start(struct iec61850_receiver *r) { switch (r->type) { - case iec61850_receiver::type::GOOSE: + case iec61850_receiver::Type::GOOSE: r->socket = GooseReceiver_startThreadless(r->goose); break; - case iec61850_receiver::type::SAMPLED_VALUES: + case iec61850_receiver::Type::SAMPLED_VALUES: r->socket = SVReceiver_startThreadless(r->sv); break; } @@ -245,11 +245,11 @@ int iec61850_receiver_stop(struct iec61850_receiver *r) EthernetHandleSet_removeSocket(hset, r->socket); switch (r->type) { - case iec61850_receiver::type::GOOSE: + case iec61850_receiver::Type::GOOSE: GooseReceiver_stopThreadless(r->goose); break; - case iec61850_receiver::type::SAMPLED_VALUES: + case iec61850_receiver::Type::SAMPLED_VALUES: SVReceiver_stopThreadless(r->sv); break; } @@ -260,11 +260,11 @@ int iec61850_receiver_stop(struct iec61850_receiver *r) int iec61850_receiver_destroy(struct iec61850_receiver *r) { switch (r->type) { - case iec61850_receiver::type::GOOSE: + case iec61850_receiver::Type::GOOSE: GooseReceiver_destroy(r->goose); break; - case iec61850_receiver::type::SAMPLED_VALUES: + case iec61850_receiver::Type::SAMPLED_VALUES: SVReceiver_destroy(r->sv); break; } @@ -274,7 +274,7 @@ int iec61850_receiver_destroy(struct iec61850_receiver *r) return 0; } -struct iec61850_receiver * iec61850_receiver_lookup(enum iec61850_receiver::type t, const char *intf) +struct iec61850_receiver * iec61850_receiver_lookup(enum iec61850_receiver::Type t, const char *intf) { for (unsigned i = 0; i < vlist_length(&receivers); i++) { struct iec61850_receiver *r = (struct iec61850_receiver *) vlist_at(&receivers, i); @@ -286,7 +286,7 @@ struct iec61850_receiver * iec61850_receiver_lookup(enum iec61850_receiver::type return nullptr; } -struct iec61850_receiver * iec61850_receiver_create(enum iec61850_receiver::type t, const char *intf) +struct iec61850_receiver * iec61850_receiver_create(enum iec61850_receiver::Type t, const char *intf) { struct iec61850_receiver *r; @@ -301,12 +301,12 @@ struct iec61850_receiver * iec61850_receiver_create(enum iec61850_receiver::type r->type = t; switch (r->type) { - case iec61850_receiver::type::GOOSE: + case iec61850_receiver::Type::GOOSE: r->goose = GooseReceiver_create(); GooseReceiver_setInterfaceId(r->goose, r->interface); break; - case iec61850_receiver::type::SAMPLED_VALUES: + case iec61850_receiver::Type::SAMPLED_VALUES: r->sv = SVReceiver_create(); SVReceiver_setInterfaceId(r->sv, r->interface); break; diff --git a/lib/nodes/iec61850_sv.cpp b/lib/nodes/iec61850_sv.cpp index 4b563a0c0..e791ab9cd 100644 --- a/lib/nodes/iec61850_sv.cpp +++ b/lib/nodes/iec61850_sv.cpp @@ -74,7 +74,7 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscribe } smp->sequence = smpcnt; - smp->flags = SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + smp->flags = (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; smp->length = 0; smp->signals = &n->in.signals; @@ -83,7 +83,7 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscribe smp->ts.origin.tv_sec = refrtm / 1000; smp->ts.origin.tv_nsec = (refrtm % 1000) * 1000000; - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; } unsigned offset = 0; @@ -94,35 +94,35 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscribe continue; switch (td->iec_type) { - case iec61850_type::INT8: + case IEC61850Type::INT8: smp->data[j].i = SVSubscriber_ASDU_getINT8(asdu, offset); break; - case iec61850_type::INT16: + case IEC61850Type::INT16: smp->data[j].i = SVSubscriber_ASDU_getINT16(asdu, offset); break; - case iec61850_type::INT32: + case IEC61850Type::INT32: smp->data[j].i = SVSubscriber_ASDU_getINT32(asdu, offset); break; - case iec61850_type::INT8U: + case IEC61850Type::INT8U: smp->data[j].i = SVSubscriber_ASDU_getINT8U(asdu, offset); break; - case iec61850_type::INT16U: + case IEC61850Type::INT16U: smp->data[j].i = SVSubscriber_ASDU_getINT16U(asdu, offset); break; - case iec61850_type::INT32U: + case IEC61850Type::INT32U: smp->data[j].i = SVSubscriber_ASDU_getINT32U(asdu, offset); break; - case iec61850_type::FLOAT32: + case IEC61850Type::FLOAT32: smp->data[j].f = SVSubscriber_ASDU_getFLOAT32(asdu, offset); break; - case iec61850_type::FLOAT64: + case IEC61850Type::FLOAT64: smp->data[j].f = SVSubscriber_ASDU_getFLOAT64(asdu, offset); break; @@ -282,19 +282,19 @@ int iec61850_sv_start(struct node *n) struct iec61850_type_descriptor *td = (struct iec61850_type_descriptor *) vlist_at(&i->out.signals, k); switch (td->iec_type) { - case iec61850_type::INT8: + case IEC61850Type::INT8: SVPublisher_ASDU_addINT8(i->out.asdu); break; - case iec61850_type::INT32: + case IEC61850Type::INT32: SVPublisher_ASDU_addINT32(i->out.asdu); break; - case iec61850_type::FLOAT32: + case IEC61850Type::FLOAT32: SVPublisher_ASDU_addFLOAT(i->out.asdu); break; - case iec61850_type::FLOAT64: + case IEC61850Type::FLOAT64: SVPublisher_ASDU_addFLOAT64(i->out.asdu); break; @@ -316,7 +316,7 @@ int iec61850_sv_start(struct node *n) /* Start subscriber */ if (i->in.enabled) { - struct iec61850_receiver *r = iec61850_receiver_create(iec61850_receiver::type::SAMPLED_VALUES, i->interface); + struct iec61850_receiver *r = iec61850_receiver_create(iec61850_receiver::Type::SAMPLED_VALUES, i->interface); i->in.receiver = r->sv; i->in.subscriber = SVSubscriber_create(i->dst_address.ether_addr_octet, i->app_id); @@ -332,7 +332,7 @@ int iec61850_sv_start(struct node *n) if (ret) return ret; - ret = queue_signalled_init(&i->in.queue, 1024, &memory_hugepage, 0); + ret = queue_signalled_init(&i->in.queue, 1024, &memory_hugepage); if (ret) return ret; @@ -340,7 +340,7 @@ int iec61850_sv_start(struct node *n) struct iec61850_type_descriptor *td = (struct iec61850_type_descriptor *) vlist_at(&i->in.signals, k); struct signal *sig = (struct signal *) vlist_at(&n->in.signals, k); - if (sig->type == SIGNAL_TYPE_INVALID) + if (sig->type == SignalType::INVALID) sig->type = td->type; else if (sig->type != td->type) return -1; @@ -416,33 +416,33 @@ int iec61850_sv_write(struct node *n, struct sample *smps[], unsigned cnt, unsig double fval = 0; switch (td->iec_type) { - case iec61850_type::INT8: - case iec61850_type::INT32: - ival = sample_format(smps[j], k) == SIGNAL_TYPE_FLOAT ? smps[j]->data[k].f : smps[j]->data[k].i; + case IEC61850Type::INT8: + case IEC61850Type::INT32: + ival = sample_format(smps[j], k) == SignalType::FLOAT ? smps[j]->data[k].f : smps[j]->data[k].i; break; - case iec61850_type::FLOAT32: - case iec61850_type::FLOAT64: - fval = sample_format(smps[j], k) == SIGNAL_TYPE_FLOAT ? smps[j]->data[k].f : smps[j]->data[k].i; + case IEC61850Type::FLOAT32: + case IEC61850Type::FLOAT64: + fval = sample_format(smps[j], k) == SignalType::FLOAT ? smps[j]->data[k].f : smps[j]->data[k].i; break; default: { } } switch (td->iec_type) { - case iec61850_type::INT8: + case IEC61850Type::INT8: SVPublisher_ASDU_setINT8(i->out.asdu, offset, ival); break; - case iec61850_type::INT32: + case IEC61850Type::INT32: SVPublisher_ASDU_setINT32(i->out.asdu, offset, ival); break; - case iec61850_type::FLOAT32: + case IEC61850Type::FLOAT32: SVPublisher_ASDU_setFLOAT(i->out.asdu, offset, fval); break; - case iec61850_type::FLOAT64: + case IEC61850Type::FLOAT64: SVPublisher_ASDU_setFLOAT64(i->out.asdu, offset, fval); break; @@ -454,7 +454,7 @@ int iec61850_sv_write(struct node *n, struct sample *smps[], unsigned cnt, unsig SVPublisher_ASDU_setSmpCnt(i->out.asdu, smps[j]->sequence); - if (smps[j]->flags & SAMPLE_HAS_TS_ORIGIN) { + if (smps[j]->flags & (int) SampleFlags::HAS_TS_ORIGIN) { uint64_t refrtm = smps[j]->ts.origin.tv_sec * 1000 + smps[j]->ts.origin.tv_nsec / 1000000; SVPublisher_ASDU_setRefrTm(i->out.asdu, refrtm); @@ -479,13 +479,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "iec61850-9-2"; p.description = "IEC 61850-9-2 (Sampled Values)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct iec61850_sv); p.node.type.start = iec61850_type_start; @@ -505,7 +505,7 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/infiniband.cpp b/lib/nodes/infiniband.cpp index 6d68f65af..d2faabec7 100644 --- a/lib/nodes/infiniband.cpp +++ b/lib/nodes/infiniband.cpp @@ -476,7 +476,7 @@ static void ib_continue_as_listen(struct node *n, struct rdma_cm_event *event) "continue as listening node in such cases, set use_fallback = true in the configuration", node_name(n)); - n->state = STATE_STARTED; + n->state = State::STARTED; /* Acknowledge event */ rdma_ack_cm_event(event); @@ -508,7 +508,7 @@ void * ib_rdma_cm_event_thread(void *n) debug(LOG_IB | 1, "Started rdma_cm_event thread of node %s", node_name(node)); /* Wait until node is completely started */ - while (node->state != STATE_STARTED); + while (node->state != State::STARTED); /* Monitor event channel */ while (rdma_get_cm_event(ib->ctx.ec, &event) == 0) { @@ -551,9 +551,9 @@ void * ib_rdma_cm_event_thread(void *n) * with rdma_connect. */ if (ib->conn.port_space == RDMA_PS_UDP && !ib->is_source) - node->state = STATE_CONNECTED; + node->state = State::CONNECTED; else - node->state = STATE_PENDING_CONNECT; + node->state = State::PENDING_CONNECT; break; @@ -578,14 +578,14 @@ void * ib_rdma_cm_event_thread(void *n) ib->conn.ud.ah = ibv_create_ah(ib->ctx.pd, &ib->conn.ud.ud.ah_attr); } - node->state = STATE_CONNECTED; + node->state = State::CONNECTED; info("Connection established in node %s", node_name(node)); break; case RDMA_CM_EVENT_DISCONNECTED: - node->state = STATE_STARTED; + node->state = State::STARTED; ret = ib_disconnect(node); @@ -686,7 +686,7 @@ int ib_stop(struct node *n) * Will flush all outstanding WRs to the Completion Queue and * will call RDMA_CM_EVENT_DISCONNECTED if that is done. */ - if (n->state == STATE_CONNECTED && ib->conn.port_space != RDMA_PS_UDP) { + if (n->state == State::CONNECTED && ib->conn.port_space != RDMA_PS_UDP) { ret = rdma_disconnect(ib->ctx.id); if (ret) @@ -739,7 +739,7 @@ int ib_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *relea debug(LOG_IB | 15, "ib_read is called"); - if (n->state == STATE_CONNECTED || n->state == STATE_PENDING_CONNECT) { + if (n->state == State::CONNECTED || n->state == State::PENDING_CONNECT) { max_wr_post = cnt; @@ -750,10 +750,10 @@ int ib_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *relea for (int i = 0;; i++) { if (i % CHK_PER_ITER == CHK_PER_ITER - 1) pthread_testcancel(); - /* If IB node disconnects or if it is still in STATE_PENDING_CONNECT, ib_read + /* If IB node disconnects or if it is still in State::PENDING_CONNECT, ib_read * should return immediately if this condition holds */ - if (n->state != STATE_CONNECTED) return 0; + if (n->state != State::CONNECTED) return 0; wcs = ibv_poll_cq(ib->ctx.recv_cq, cnt, wc); if (wcs) { @@ -861,7 +861,7 @@ int ib_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *relea smps[j]->length = SAMPLE_NUMBER_OF_VALUES(wc[j].byte_len - correction); smps[j]->ts.received = ts_receive; - smps[j]->flags = (SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_TS_RECEIVED | SAMPLE_HAS_SEQUENCE); + smps[j]->flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_TS_RECEIVED | (int) SampleFlags::HAS_SEQUENCE; } } @@ -881,7 +881,7 @@ int ib_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *rele debug(LOG_IB | 10, "ib_write is called"); - if (n->state == STATE_CONNECTED) { + if (n->state == State::CONNECTED) { *release = 0; /* First, write */ @@ -1006,13 +1006,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "infiniband"; p.description = "Infiniband interface (libibverbs, librdmacm)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct infiniband); p.node.pool_size = 8192; @@ -1033,6 +1033,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/influxdb.cpp b/lib/nodes/influxdb.cpp index 05aa809a1..f872e0e33 100644 --- a/lib/nodes/influxdb.cpp +++ b/lib/nodes/influxdb.cpp @@ -138,9 +138,9 @@ int influxdb_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned union signal_data *data = &smp->data[k]; if ( - sig->type != SIGNAL_TYPE_BOOLEAN && - sig->type != SIGNAL_TYPE_INTEGER && - sig->type != SIGNAL_TYPE_INTEGER + sig->type != SignalType::BOOLEAN && + sig->type != SignalType::INTEGER && + sig->type != SignalType::INTEGER ) { warning("Unsupported signal format for node %s. Skipping", node_name(n)); continue; @@ -158,15 +158,15 @@ int influxdb_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned strcatf(&buf, "value%d=", j); switch (sig->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: strcatf(&buf, "%s", data->b ? "true" : "false"); break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: strcatf(&buf, "%f", data->f); break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: strcatf(&buf, "%" PRIi64, data->i); break; @@ -204,13 +204,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "influxdb"; p.description = "Write results to InfluxDB"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct influxdb); p.node.parse = influxdb_parse; @@ -226,6 +226,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/loopback.cpp b/lib/nodes/loopback.cpp index 0c10fc720..23d654713 100644 --- a/lib/nodes/loopback.cpp +++ b/lib/nodes/loopback.cpp @@ -39,7 +39,7 @@ int loopback_parse(struct node *n, json_t *cfg) int ret; /* Default values */ - l->queueflags = QUEUE_SIGNALLED_AUTO; + l->mode = QueueSignalledMode::AUTO; l->queuelen = DEFAULT_QUEUE_LENGTH; ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: s }", @@ -51,18 +51,18 @@ int loopback_parse(struct node *n, json_t *cfg) if (mode_str) { if (!strcmp(mode_str, "auto")) - l->queueflags = QUEUE_SIGNALLED_AUTO; + l->mode = QueueSignalledMode::AUTO; #ifdef HAVE_EVENTFD else if (!strcmp(mode_str, "eventfd")) - l->queueflags = QUEUE_SIGNALLED_EVENTFD; + l->mode = QueueSignalledMode::EVENTFD; #endif else if (!strcmp(mode_str, "pthread")) - l->queueflags = QUEUE_SIGNALLED_PTHREAD; + l->mode = QueueSignalledMode::PTHREAD; else if (!strcmp(mode_str, "polling")) - l->queueflags = QUEUE_SIGNALLED_POLLING; + l->mode = QueueSignalledMode::POLLING; #ifdef __APPLE__ else if (!strcmp(mode_str, "pipe")) - l->queueflags = QUEUE_SIGNALLED_PIPE; + l->mode = QueueSignalledMode::PIPE; #endif /* __APPLE__ */ else error("Unknown mode '%s' in node %s", mode_str, node_name(n)); @@ -85,7 +85,7 @@ int loopback_start(struct node *n) if (ret) return ret; - return queue_signalled_init(&l->queue, l->queuelen, &memory_hugepage, l->queueflags); + return queue_signalled_init(&l->queue, l->queuelen, &memory_hugepage, l->mode); } int loopback_stop(struct node *n) @@ -156,15 +156,15 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "loopback"; p.description = "Loopback to connect multiple paths"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; - p.node.flags = NODE_TYPE_PROVIDES_SIGNALS; + p.node.flags = (int) NodeFlags::PROVIDES_SIGNALS; p.node.size = sizeof(struct loopback); p.node.parse = loopback_parse; p.node.print = loopback_print; @@ -180,6 +180,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index f9ca8acd0..fdfbb638c 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -311,7 +311,7 @@ int mqtt_start(struct node *n) mosquitto_message_callback_set(m->client, mqtt_message_cb); mosquitto_subscribe_callback_set(m->client, mqtt_subscribe_cb); - ret = io_init(&m->io, m->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&m->io, m->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -323,7 +323,7 @@ int mqtt_start(struct node *n) if (ret) return ret; - ret = queue_signalled_init(&m->queue, 1024, &memory_hugepage, 0); + ret = queue_signalled_init(&m->queue, 1024, &memory_hugepage); if (ret) return ret; @@ -453,13 +453,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "mqtt"; p.description = "Message Queuing Telemetry Transport (libmosquitto)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct mqtt); p.node.type.start = mqtt_type_start; @@ -481,6 +481,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/nanomsg.cpp b/lib/nodes/nanomsg.cpp index c9a2a805b..5382bd4ad 100644 --- a/lib/nodes/nanomsg.cpp +++ b/lib/nodes/nanomsg.cpp @@ -155,7 +155,7 @@ int nanomsg_start(struct node *n) int ret; struct nanomsg *m = (struct nanomsg *) n->_vd; - ret = io_init(&m->io, m->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&m->io, m->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -296,13 +296,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "nanomsg"; p.description = "scalability protocols library (libnanomsg)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct nanomsg); p.node.type.stop = nanomsg_type_stop; @@ -322,6 +322,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/ngsi.cpp b/lib/nodes/ngsi.cpp index ca149017a..4c8a8a6a4 100644 --- a/lib/nodes/ngsi.cpp +++ b/lib/nodes/ngsi.cpp @@ -591,13 +591,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "ngsi"; p.description = "OMA Next Generation Services Interface 10 (libcurl, libjansson)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0, /* unlimited */ p.node.size = sizeof(struct ngsi); p.node.type.start = ngsi_type_start; @@ -616,6 +616,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/opal.cpp b/lib/nodes/opal.cpp index a17a949a1..12864299d 100644 --- a/lib/nodes/opal.cpp +++ b/lib/nodes/opal.cpp @@ -224,7 +224,7 @@ int opal_read(struct node *n, struct pool *pool, unsigned cnt) ret = OpalWaitForAsyncSendRequest(&id); if (ret != EOK) { state = OpalGetAsyncModelState(); - if ((state == STATE_RESET) || (state == STATE_STOP)) + if ((state == State::RESET) || (state == State::STOP)) error("OpalGetAsyncModelState(): Model stopped or resetted!"); return -1; /* @todo correct return value */ @@ -264,7 +264,7 @@ int opal_read(struct node *n, struct pool *pool, unsigned cnt) /* Before continuing, we make sure that the real-time model * has not been stopped. If it has, we quit. */ state = OpalGetAsyncModelState(); - if ((state == STATE_RESET) || (state == STATE_STOP)) + if ((state == State::RESET) || (state == State::STOP)) error("OpalGetAsyncModelState(): Model stopped or resetted!"); return 1; @@ -284,7 +284,7 @@ int opal_write(struct node *n, struct pool *pool, unsigned cnt) error("The OPAL-RT node type does not support combining!"); state = OpalGetAsyncModelState(); - if ((state == STATE_RESET) || (state == STATE_STOP)) + if ((state == State::RESET) || (state == State::STOP)) error("OpalGetAsyncModelState(): Model stopped or resetted!"); OpalSetAsyncRecvIconStatus(m->sequence, o->recv_id); /* Set the Status to the message ID */ @@ -307,13 +307,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "opal"; p.description = "run as OPAL Asynchronous Process (libOpalAsyncApi)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectoroize = 1; p.node.size = sizeof(struct opal); p.node.type.start = opal_type_start; @@ -331,6 +331,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/rtp.cpp b/lib/nodes/rtp.cpp index d7ea79a32..33adfdde1 100644 --- a/lib/nodes/rtp.cpp +++ b/lib/nodes/rtp.cpp @@ -43,7 +43,7 @@ extern "C" { #include #include #include -#include +#include #include #include @@ -108,7 +108,7 @@ int rtp_init(struct node *n) r->aimd.log = nullptr; r->rtcp.enabled = false; - r->aimd.rate_hook_type = RTCP_HOOK_DISABLED; + r->aimd.rate_hook_type = RTPHookType::DISABLED; return 0; } @@ -168,14 +168,14 @@ int rtp_parse(struct node *n, json_t *cfg) /* AIMD Hook type */ if (!r->rtcp.enabled) - r->aimd.rate_hook_type = RTCP_HOOK_DISABLED; + r->aimd.rate_hook_type = RTPHookType::DISABLED; else if (hook_type) { if (!strcmp(hook_type, "decimate")) - r->aimd.rate_hook_type = RTCP_HOOK_DECIMATE; + r->aimd.rate_hook_type = RTPHookType::DECIMATE; else if (!strcmp(hook_type, "limit_rate")) - r->aimd.rate_hook_type = RTCP_HOOK_LIMIT_RATE; + r->aimd.rate_hook_type = RTPHookType::LIMIT_RATE; else if (!strcmp(hook_type, "disabled")) - r->aimd.rate_hook_type = RTCP_HOOK_DISABLED; + r->aimd.rate_hook_type = RTPHookType::DISABLED; else r->logger->error("Unknown RTCP hook_type: {}", hook_type); } @@ -237,15 +237,15 @@ char * rtp_print(struct node *n) const char *hook_type; switch (r->aimd.rate_hook_type) { - case RTCP_HOOK_DECIMATE: + case RTPHookType::DECIMATE: hook_type = "decimate"; break; - case RTCP_HOOK_LIMIT_RATE: + case RTPHookType::LIMIT_RATE: hook_type = "limit_rate"; break; - case RTCP_HOOK_DISABLED: + case RTPHookType::DISABLED: hook_type = "disabled"; break; @@ -321,12 +321,12 @@ int rtp_start(struct node *n) struct rtp *r = (struct rtp *) n->_vd; /* Initialize queue */ - ret = queue_signalled_init(&r->recv_queue, 1024, &memory_heap, 0); + ret = queue_signalled_init(&r->recv_queue, 1024, &memory_heap); if (ret) return ret; /* Initialize IO */ - ret = io_init(&r->io, r->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&r->io, r->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -344,14 +344,14 @@ int rtp_start(struct node *n) return ret; /* Initialize AIMD hook */ - if (r->aimd.rate_hook_type != RTCP_HOOK_DISABLED) { + if (r->aimd.rate_hook_type != RTPHookType::DISABLED) { #ifdef WITH_HOOKS switch (r->aimd.rate_hook_type) { - case RTCP_HOOK_DECIMATE: + case RTPHookType::DECIMATE: r->aimd.rate_hook = new DecimateHook(nullptr, n, 0, 0); break; - case RTCP_HOOK_LIMIT_RATE: + case RTPHookType::LIMIT_RATE: r->aimd.rate_hook = new LimitRateHook(nullptr, n, 0, 0); break; @@ -609,7 +609,7 @@ int rtp_netem_fds(struct node *n, int fds[]) __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "rtp"; @@ -618,8 +618,8 @@ static void register_plugin() { #else p.description = "real-time transport protocol (libre)"; #endif - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct rtp); p.node.type.start = rtp_type_start; @@ -642,6 +642,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/shmem.cpp b/lib/nodes/shmem.cpp index 87dbcda8c..37d61769e 100644 --- a/lib/nodes/shmem.cpp +++ b/lib/nodes/shmem.cpp @@ -141,7 +141,7 @@ int shmem_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *re info("Shared memory segment has been closed."); - n->state = STATE_STOPPING; + n->state = State::STOPPING; return recv; } @@ -201,13 +201,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "shmem"; p.description = "POSIX shared memory interface with external processes"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct shmem); p.node.parse = shmem_parse; @@ -224,6 +224,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/signal_generator.cpp b/lib/nodes/signal_generator.cpp index d9123da8a..76f9ac9ab 100644 --- a/lib/nodes/signal_generator.cpp +++ b/lib/nodes/signal_generator.cpp @@ -30,53 +30,53 @@ using namespace villas::utils; -static enum signal_generator::type signal_generator_lookup_type(const char *type) +static enum signal_generator::SignalType signal_generator_lookup_type(const char *type) { if (!strcmp(type, "random")) - return signal_generator::type::RANDOM; + return signal_generator::SignalType::RANDOM; else if (!strcmp(type, "sine")) - return signal_generator::type::SINE; + return signal_generator::SignalType::SINE; else if (!strcmp(type, "square")) - return signal_generator::type::SQUARE; + return signal_generator::SignalType::SQUARE; else if (!strcmp(type, "triangle")) - return signal_generator::type::TRIANGLE; + return signal_generator::SignalType::TRIANGLE; else if (!strcmp(type, "ramp")) - return signal_generator::type::RAMP; + return signal_generator::SignalType::RAMP; else if (!strcmp(type, "counter")) - return signal_generator::type::COUNTER; + return signal_generator::SignalType::COUNTER; else if (!strcmp(type, "constant")) - return signal_generator::type::CONSTANT; + return signal_generator::SignalType::CONSTANT; else if (!strcmp(type, "mixed")) - return signal_generator::type::MIXED; - else - return signal_generator::type::INVALID; + return signal_generator::SignalType::MIXED; + + throw std::invalid_argument("Invalid signal type"); } -static const char * signal_generator_type_str(enum signal_generator::type type) +static const char * signal_generator_type_str(enum signal_generator::SignalType type) { switch (type) { - case signal_generator::type::CONSTANT: + case signal_generator::SignalType::CONSTANT: return "constant"; - case signal_generator::type::SINE: + case signal_generator::SignalType::SINE: return "sine"; - case signal_generator::type::TRIANGLE: + case signal_generator::SignalType::TRIANGLE: return "triangle"; - case signal_generator::type::SQUARE: + case signal_generator::SignalType::SQUARE: return "square"; - case signal_generator::type::RAMP: + case signal_generator::SignalType::RAMP: return "ramp"; - case signal_generator::type::COUNTER: + case signal_generator::SignalType::COUNTER: return "counter"; - case signal_generator::type::RANDOM: + case signal_generator::SignalType::RANDOM: return "random"; - case signal_generator::type::MIXED: + case signal_generator::SignalType::MIXED: return "mixed"; default: @@ -93,10 +93,10 @@ int signal_generator_prepare(struct node *n) for (unsigned i = 0; i < s->values; i++) { struct signal *sig = (struct signal *) alloc(sizeof(struct signal)); - int rtype = s->type == signal_generator::type::MIXED ? i % 7 : s->type; + int rtype = s->type == signal_generator::SignalType::MIXED ? i % 7 : (int) s->type; - sig->name = strdup(signal_generator_type_str((enum signal_generator::type) rtype)); - sig->type = SIGNAL_TYPE_FLOAT; /* All generated signals are of type float */ + sig->name = strdup(signal_generator_type_str((enum signal_generator::SignalType) rtype)); + sig->type = SignalType::FLOAT; /* All generated signals are of type float */ vlist_push(&n->in.signals, sig); } @@ -138,15 +138,10 @@ int signal_generator_parse(struct node *n, json_t *cfg) if (ret) jerror(&err, "Failed to parse configuration of node %s", node_name(n)); - if (type) { - ret = signal_generator_lookup_type(type); - if (ret == -1) - error("Unknown signal type '%s' of node %s", type, node_name(n)); - - s->type = (enum signal_generator::type) ret; - } + if (type) + s->type = signal_generator_lookup_type(type); else - s->type = signal_generator::type::MIXED; + s->type = signal_generator::SignalType::MIXED; return 0; } @@ -224,51 +219,54 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt, u double running = time_delta(&s->started, &ts); - t->flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_DATA | SAMPLE_HAS_SEQUENCE; + t->flags = (int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_SEQUENCE; t->ts.origin = ts; t->sequence = s->counter; t->length = MIN(s->values, t->capacity); t->signals = &n->in.signals; for (unsigned i = 0; i < MIN(s->values, t->capacity); i++) { - int rtype = (s->type != signal_generator::type::MIXED) ? s->type : i % 7; + auto rtype = (s->type != signal_generator::SignalType::MIXED) ? s->type : (signal_generator::SignalType) (i % 7); switch (rtype) { - case signal_generator::type::CONSTANT: + case signal_generator::SignalType::CONSTANT: t->data[i].f = s->offset + s->amplitude; break; - case signal_generator::type::SINE: + case signal_generator::SignalType::SINE: t->data[i].f = s->offset + s->amplitude * sin(running * s->frequency * 2 * M_PI); break; - case signal_generator::type::TRIANGLE: + case signal_generator::SignalType::TRIANGLE: t->data[i].f = s->offset + s->amplitude * (fabs(fmod(running * s->frequency, 1) - .5) - 0.25) * 4; break; - case signal_generator::type::SQUARE: + case signal_generator::SignalType::SQUARE: t->data[i].f = s->offset + s->amplitude * ( (fmod(running * s->frequency, 1) < .5) ? -1 : 1); break; - case signal_generator::type::RAMP: + case signal_generator::SignalType::RAMP: t->data[i].f = s->offset + s->amplitude * fmod(running, s->frequency); break; - case signal_generator::type::COUNTER: + case signal_generator::SignalType::COUNTER: t->data[i].f = s->offset + s->amplitude * s->counter; break; - case signal_generator::type::RANDOM: + case signal_generator::SignalType::RANDOM: s->last[i] += box_muller(0, s->stddev); t->data[i].f = s->last[i]; break; + + case signal_generator::SignalType::MIXED: + break; } } if (s->limit > 0 && s->counter >= (unsigned) s->limit) { info("Reached limit."); - n->state = STATE_STOPPING; + n->state = State::STOPPING; return -1; } @@ -306,15 +304,15 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "signal"; p.description = "Signal generator"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 1; - p.node.flags = NODE_TYPE_PROVIDES_SIGNALS; + p.node.flags = (int) NodeFlags::PROVIDES_SIGNALS; p.node.size = sizeof(struct signal_generator); p.node.parse = signal_generator_parse; p.node.prepare = signal_generator_prepare; @@ -331,6 +329,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/socket.cpp b/lib/nodes/socket.cpp index cc7388fb1..15a7b1df6 100644 --- a/lib/nodes/socket.cpp +++ b/lib/nodes/socket.cpp @@ -60,7 +60,7 @@ int socket_type_start(villas::node::SuperNode *sn) struct node *n = (struct node *) vlist_at(&p.node.instances, i); struct socket *s = (struct socket *) n->_vd; - if (s->layer == SOCKET_LAYER_UNIX) + if (s->layer == SocketLayer::UNIX) continue; /* Determine outgoing interface */ @@ -80,19 +80,19 @@ char * socket_print(struct node *n) char *buf; switch (s->layer) { - case SOCKET_LAYER_UDP: + case SocketLayer::UDP: layer = "udp"; break; - case SOCKET_LAYER_IP: + case SocketLayer::IP: layer = "ip"; break; - case SOCKET_LAYER_ETH: + case SocketLayer::ETH: layer = "eth"; break; - case SOCKET_LAYER_UNIX: + case SocketLayer::UNIX: layer = "unix"; break; } @@ -127,17 +127,17 @@ int socket_check(struct node *n) struct socket *s = (struct socket *) n->_vd; /* Some checks on the addresses */ - if (s->layer != SOCKET_LAYER_UNIX) { + if (s->layer != SocketLayer::UNIX) { if (s->in.saddr.sa.sa_family != s->out.saddr.sa.sa_family) error("Address families of local and remote must match!"); } - if (s->layer == SOCKET_LAYER_IP) { + if (s->layer == SocketLayer::IP) { if (ntohs(s->in.saddr.sin.sin_port) != ntohs(s->out.saddr.sin.sin_port)) error("IP protocol numbers of local and remote must match!"); } #ifdef WITH_SOCKET_LAYER_ETH - else if (s->layer == SOCKET_LAYER_ETH) { + else if (s->layer == SocketLayer::ETH) { if (ntohs(s->in.saddr.sll.sll_protocol) != ntohs(s->out.saddr.sll.sll_protocol)) error("Ethertypes of local and remote must match!"); @@ -164,7 +164,7 @@ int socket_start(struct node *n) int ret; /* Initialize IO */ - ret = io_init(&s->io, s->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&s->io, s->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -174,21 +174,21 @@ int socket_start(struct node *n) /* Create socket */ switch (s->layer) { - case SOCKET_LAYER_UDP: + case SocketLayer::UDP: s->sd = socket(s->in.saddr.sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); break; - case SOCKET_LAYER_IP: + case SocketLayer::IP: s->sd = socket(s->in.saddr.sa.sa_family, SOCK_RAW, ntohs(s->in.saddr.sin.sin_port)); break; #ifdef WITH_SOCKET_LAYER_ETH - case SOCKET_LAYER_ETH: + case SocketLayer::ETH: s->sd = socket(s->in.saddr.sa.sa_family, SOCK_DGRAM, s->in.saddr.sll.sll_protocol); break; #endif /* WITH_SOCKET_LAYER_ETH */ - case SOCKET_LAYER_UNIX: + case SocketLayer::UNIX: s->sd = socket(s->in.saddr.sa.sa_family, SOCK_DGRAM, 0); break; @@ -200,7 +200,7 @@ int socket_start(struct node *n) serror("Failed to create socket"); /* Delete Unix domain socket if already existing */ - if (s->layer == SOCKET_LAYER_UNIX) { + if (s->layer == SocketLayer::UNIX) { ret = unlink(s->in.saddr.sun.sun_path); if (ret && errno != ENOENT) return ret; @@ -251,8 +251,8 @@ int socket_start(struct node *n) /* Set socket priority, QoS or TOS IP options */ int prio; switch (s->layer) { - case SOCKET_LAYER_UDP: - case SOCKET_LAYER_IP: + case SocketLayer::UDP: + case SocketLayer::IP: prio = IPTOS_LOWDELAY; if (setsockopt(s->sd, IPPROTO_IP, IP_TOS, &prio, sizeof(prio))) serror("Failed to set type of service (QoS)"); @@ -348,7 +348,7 @@ int socket_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r ptr = s->in.buf; /* Strip IP header from packet */ - if (s->layer == SOCKET_LAYER_IP) { + if (s->layer == SocketLayer::IP) { struct ip *iphdr = (struct ip *) ptr; bytes -= iphdr->ip_hl * 4; @@ -357,7 +357,7 @@ int socket_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r /* SOCK_RAW IP sockets to not provide the IP protocol number via recvmsg() * So we simply set it ourself. */ - if (s->layer == SOCKET_LAYER_IP) { + if (s->layer == SocketLayer::IP) { switch (src.sa.sa_family) { case AF_INET: src.sin.sin_port = s->out.saddr.sin.sin_port; @@ -436,7 +436,7 @@ retry: ret = io_sprint(&s->io, s->out.buf, s->out.buflen, &wbytes, smps, cnt); retry2: bytes = sendto(s->sd, s->out.buf, wbytes, 0, (struct sockaddr *) &s->out.saddr, addrlen); if (bytes < 0) { if ((errno == EPERM) || - (errno == ENOENT && s->layer == SOCKET_LAYER_UNIX)) + (errno == ENOENT && s->layer == SocketLayer::UNIX)) warning("Failed send to node %s: %s", node_name(n), strerror(errno)); else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { warning("socket: send would block"); @@ -465,7 +465,7 @@ int socket_parse(struct node *n, json_t *cfg) json_error_t err; /* Default values */ - s->layer = SOCKET_LAYER_UDP; + s->layer = SocketLayer::UDP; s->verify_source = 0; ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s: { s: s }, s: { s: s, s?: b, s?: o } }", @@ -489,15 +489,15 @@ int socket_parse(struct node *n, json_t *cfg) /* IP layer */ if (layer) { if (!strcmp(layer, "ip")) - s->layer = SOCKET_LAYER_IP; + s->layer = SocketLayer::IP; #ifdef WITH_SOCKET_LAYER_ETH else if (!strcmp(layer, "eth")) - s->layer = SOCKET_LAYER_ETH; + s->layer = SocketLayer::ETH; #endif /* WITH_SOCKET_LAYER_ETH */ else if (!strcmp(layer, "udp")) - s->layer = SOCKET_LAYER_UDP; + s->layer = SocketLayer::UDP; else if (!strcmp(layer, "unix") || !strcmp(layer, "local")) - s->layer = SOCKET_LAYER_UNIX; + s->layer = SocketLayer::UNIX; else error("Invalid layer '%s' for node %s", layer, node_name(n)); } @@ -562,7 +562,7 @@ int socket_fds(struct node *n, int fds[]) __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "socket"; @@ -571,8 +571,8 @@ static void register_plugin() { #else p.description = "BSD network sockets for Ethernet / IP / UDP"; #endif - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct socket); p.node.type.start = socket_type_start; @@ -593,6 +593,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/stats.cpp b/lib/nodes/stats.cpp index 55316bf35..73df9369e 100644 --- a/lib/nodes/stats.cpp +++ b/lib/nodes/stats.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -231,7 +231,7 @@ int stats_node_read(struct node *n, struct sample *smps[], unsigned cnt, unsigne } smps[0]->length = len; - smps[0]->flags = SAMPLE_HAS_DATA; + smps[0]->flags = (int) SampleFlags::HAS_DATA; smps[0]->signals = &n->in.signals; return 1; @@ -250,13 +250,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "stats"; p.description = "Send statistics to another node"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 1; p.node.flags = 0; p.node.size = sizeof(struct stats_node); @@ -276,6 +276,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/test_rtt.cpp b/lib/nodes/test_rtt.cpp index f7166e6a8..46a6dc82c 100644 --- a/lib/nodes/test_rtt.cpp +++ b/lib/nodes/test_rtt.cpp @@ -111,7 +111,7 @@ int test_rtt_prepare(struct node *n) strftime(c->filename_formatted, NAME_MAX, c->filename, &tm); } - ret = signal_list_generate(&n->in.signals, max_values, SIGNAL_TYPE_FLOAT); + ret = signal_list_generate(&n->in.signals, max_values, SignalType::FLOAT); if (ret) return ret; @@ -294,7 +294,7 @@ int test_rtt_start(struct node *n) } } - ret = io_init(&t->io, t->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_DATA); + ret = io_init(&t->io, t->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_DATA); if (ret) return ret; @@ -354,7 +354,7 @@ int test_rtt_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned if ((unsigned) t->current >= vlist_length(&t->cases)) { info("This was the last case. Stopping node %s", node_name(n)); - n->state = STATE_STOPPING; + n->state = State::STOPPING; return -1; } @@ -394,7 +394,7 @@ int test_rtt_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned smps[i]->length = c->values; smps[i]->sequence = t->counter; smps[i]->ts.origin = now; - smps[i]->flags = SAMPLE_HAS_DATA | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_TS_ORIGIN; + smps[i]->flags = (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_TS_ORIGIN; t->counter++; } @@ -437,15 +437,15 @@ int test_rtt_poll_fds(struct node *n, int fds[]) __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "test_rtt"; p.description = "Test round-trip time with loopback"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; - p.node.flags = NODE_TYPE_PROVIDES_SIGNALS; + p.node.flags = (int) NodeFlags::PROVIDES_SIGNALS; p.node.size = sizeof(struct test_rtt); p.node.parse = test_rtt_parse; p.node.prepare = test_rtt_prepare; @@ -462,6 +462,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/uldaq.cpp b/lib/nodes/uldaq.cpp index ae36d331d..42f40469f 100644 --- a/lib/nodes/uldaq.cpp +++ b/lib/nodes/uldaq.cpp @@ -457,7 +457,7 @@ int uldaq_check(struct node *n) struct signal *s = (struct signal *) vlist_at(&n->in.signals, i); AiQueueElement *q = &u->in.queues[i]; - if (s->type != SIGNAL_TYPE_FLOAT) { + if (s->type != SignalType::FLOAT) { warning("Node '%s' only supports signals of type = float!", node_name(n)); return -1; } @@ -626,7 +626,7 @@ int uldaq_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *re smp->length = u->in.channel_count; smp->signals = &n->in.signals; smp->sequence = u->sequence++; - smp->flags = SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA; + smp->flags = (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA; } u->in.buffer_pos += u->in.channel_count * cnt; @@ -640,13 +640,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "uldaq"; p.description = "Measurement Computing DAQ devices like UL201 (libuldaq)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.flags = 0; p.node.size = sizeof(struct uldaq); @@ -665,6 +665,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/websocket.cpp b/lib/nodes/websocket.cpp index 025e688ee..cf5a40ad2 100644 --- a/lib/nodes/websocket.cpp +++ b/lib/nodes/websocket.cpp @@ -42,7 +42,7 @@ using namespace villas::utils; #define DEFAULT_WEBSOCKET_BUFFER_SIZE (1 << 12) /* Private static storage */ -static struct vlist connections = { .state = STATE_DESTROYED }; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */ +static struct vlist connections = { .state = State::DESTROYED }; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */ static villas::node::Web *web; @@ -60,13 +60,13 @@ static char * websocket_connection_name(struct websocket_connection *c) strcatf(&c->_name, "remote.ip=%s, remote.name=%s", ip, name); } - else if (c->mode == websocket_connection::mode::CLIENT && c->destination != nullptr) + else if (c->mode == websocket_connection::Mode::CLIENT && c->destination != nullptr) strcatf(&c->_name, "dest=%s:%d", c->destination->info.address, c->destination->info.port); if (c->node) strcatf(&c->_name, ", node=%s", node_name(c->node)); - strcatf(&c->_name, ", mode=%s", c->mode == websocket_connection::mode::CLIENT ? "client" : "server"); + strcatf(&c->_name, ", mode=%s", c->mode == websocket_connection::Mode::CLIENT ? "client" : "server"); } return c->_name; @@ -90,7 +90,7 @@ static int websocket_connection_init(struct websocket_connection *c) if (ret) return ret; - ret = io_init(&c->io, c->format, &c->node->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&c->io, c->format, &c->node->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -106,7 +106,7 @@ static int websocket_connection_init(struct websocket_connection *c) if (ret) return ret; - c->state = websocket_connection::state::INITIALIZED; + c->state = websocket_connection::State::INITIALIZED; return 0; } @@ -115,7 +115,7 @@ static int websocket_connection_destroy(struct websocket_connection *c) { int ret; - assert(c->state != websocket_connection::state::DESTROYED); + assert(c->state != websocket_connection::State::DESTROYED); if (c->_name) free(c->_name); @@ -145,7 +145,7 @@ static int websocket_connection_destroy(struct websocket_connection *c) c->wsi = nullptr; c->_name = nullptr; - c->state = websocket_connection::state::DESTROYED; + c->state = websocket_connection::State::DESTROYED; return 0; } @@ -154,7 +154,7 @@ static int websocket_connection_write(struct websocket_connection *c, struct sam { int pushed; - if (c->state != websocket_connection::state::INITIALIZED) + if (c->state != websocket_connection::State::INITIALIZED) return -1; pushed = queue_push_many(&c->queue, (void **) smps, cnt); @@ -188,14 +188,14 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi case LWS_CALLBACK_CLIENT_ESTABLISHED: case LWS_CALLBACK_ESTABLISHED: c->wsi = wsi; - c->state = websocket_connection::state::ESTABLISHED; + c->state = websocket_connection::State::ESTABLISHED; info("Established WebSocket connection: %s", websocket_connection_name(c)); if (reason == LWS_CALLBACK_CLIENT_ESTABLISHED) - c->mode = websocket_connection::mode::CLIENT; + c->mode = websocket_connection::Mode::CLIENT; else { - c->mode = websocket_connection::mode::SERVER; + c->mode = websocket_connection::Mode::SERVER; /* We use the URI to associate this connection to a node * and choose a protocol. * @@ -255,7 +255,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - c->state = websocket_connection::state::ERROR; + c->state = websocket_connection::State::ERROR; warning("Failed to establish WebSocket connection: %s, reason=%s", websocket_connection_name(c), in ? (char *) in : "unkown"); @@ -264,17 +264,17 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi case LWS_CALLBACK_CLOSED: debug(LOG_WEBSOCKET | 10, "Closed WebSocket connection: %s", websocket_connection_name(c)); - if (c->state != websocket_connection::state::SHUTDOWN) { + if (c->state != websocket_connection::State::SHUTDOWN) { /** @todo Attempt reconnect here */ } - if (connections.state == STATE_INITIALIZED) + if (connections.state == State::INITIALIZED) vlist_remove_all(&connections, c); - if (c->state == websocket_connection::state::INITIALIZED) + if (c->state == websocket_connection::State::INITIALIZED) websocket_connection_destroy(c); - if (c->mode == websocket_connection::mode::CLIENT) + if (c->mode == websocket_connection::Mode::CLIENT) free(c); break; @@ -288,7 +288,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi size_t wbytes; io_sprint(&c->io, c->buffers.send.buf + LWS_PRE, c->buffers.send.size - LWS_PRE, &wbytes, smps, pulled); - ret = lws_write(wsi, (unsigned char *) c->buffers.send.buf + LWS_PRE, wbytes, c->io.flags & IO_HAS_BINARY_PAYLOAD ? LWS_WRITE_BINARY : LWS_WRITE_TEXT); + ret = lws_write(wsi, (unsigned char *) c->buffers.send.buf + LWS_PRE, wbytes, c->io.flags & (int) IOFlags::HAS_BINARY_PAYLOAD ? LWS_WRITE_BINARY : LWS_WRITE_TEXT); sample_decref_many(smps, pulled); @@ -300,7 +300,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi if (queue_available(&c->queue) > 0) lws_callback_on_writable(wsi); - else if (c->state == websocket_connection::state::SHUTDOWN) { + else if (c->state == websocket_connection::State::SHUTDOWN) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_GOINGAWAY, "Node stopped"); return -1; } @@ -347,7 +347,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi /* Set receive timestamp */ for (int i = 0; i < recvd; i++) { smps[i]->ts.received = ts_recv; - smps[i]->flags |= SAMPLE_HAS_TS_RECEIVED; + smps[i]->flags |= (int) SampleFlags::HAS_TS_RECEIVED; } enqueued = queue_signalled_push_many(&w->queue, (void **) smps, recvd); @@ -360,7 +360,7 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi buffer_clear(&c->buffers.recv); - if (c->state == websocket_connection::state::SHUTDOWN) { + if (c->state == websocket_connection::State::SHUTDOWN) { websocket_connection_close(c, wsi, LWS_CLOSE_STATUS_GOINGAWAY, "Node stopped"); return -1; } @@ -380,7 +380,7 @@ int websocket_type_start(villas::node::SuperNode *sn) vlist_init(&connections); web = sn->getWeb(); - if (web->getState() != STATE_STARTED) + if (web->getState() != State::STARTED) return -1; return 0; @@ -395,7 +395,7 @@ int websocket_start(struct node *n) if (ret) return ret; - ret = queue_signalled_init(&w->queue, DEFAULT_WEBSOCKET_QUEUE_LENGTH, &memory_hugepage, 0); + ret = queue_signalled_init(&w->queue, DEFAULT_WEBSOCKET_QUEUE_LENGTH, &memory_hugepage); if (ret) return ret; @@ -404,7 +404,7 @@ int websocket_start(struct node *n) struct websocket_destination *d = (struct websocket_destination *) vlist_at(&w->destinations, i); struct websocket_connection *c = (struct websocket_connection *) alloc(sizeof(struct websocket_connection)); - c->state = websocket_connection::state::CONNECTING; + c->state = websocket_connection::State::CONNECTING; format = strchr(d->info.path, '.'); if (format) @@ -440,7 +440,7 @@ int websocket_stop(struct node *n) if (c->node != n) continue; - c->state = websocket_connection::state::SHUTDOWN; + c->state = websocket_connection::State::SHUTDOWN; lws_callback_on_writable(c->wsi); } @@ -612,15 +612,15 @@ int websocket_poll_fds(struct node *n, int fds[]) } __attribute__((constructor(110))) static void UNIQUE(__ctor)() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "websocket"; p.description = "Send and receive samples of a WebSocket connection (libwebsockets)"; - p.type = PLUGIN_TYPE_NODE; + p.type = PluginType::NODE; p.node.vectorize = 0; /* unlimited */ p.node.size = sizeof(struct websocket); - p.node.instances.state = STATE_DESTROYED; + p.node.instances.state = State::DESTROYED; p.node.type.start = websocket_type_start; p.node.destroy = websocket_destroy; p.node.parse = websocket_parse; @@ -636,6 +636,6 @@ __attribute__((constructor(110))) static void UNIQUE(__ctor)() { } __attribute__((destructor(110))) static void UNIQUE(__dtor)() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/nodes/zeromq.cpp b/lib/nodes/zeromq.cpp index f640b7a49..48eb0f471 100644 --- a/lib/nodes/zeromq.cpp +++ b/lib/nodes/zeromq.cpp @@ -191,10 +191,10 @@ int zeromq_parse(struct node *n, json_t *cfg) if (type) { if (!strcmp(type, "pubsub")) - z->pattern = zeromq::pattern::PUBSUB; + z->pattern = zeromq::Pattern::PUBSUB; #ifdef ZMQ_BUILD_DISH else if (!strcmp(type, "radiodish")) - z->pattern = zeromq::pattern::RADIODISH; + z->pattern = zeromq::Pattern::RADIODISH; #endif else error("Invalid type for ZeroMQ node: %s", node_name_short(n)); @@ -211,12 +211,12 @@ char * zeromq_print(struct node *n) const char *pattern = nullptr; switch (z->pattern) { - case zeromq::pattern::PUBSUB: + case zeromq::Pattern::PUBSUB: pattern = "pubsub"; break; #ifdef ZMQ_BUILD_DISH - case zeromq::pattern::RADIODISH: + case zeromq::Pattern::RADIODISH: pattern = "radiodish"; break; #endif @@ -264,7 +264,7 @@ int zeromq_start(struct node *n) int ret; struct zeromq *z = (struct zeromq *) n->_vd; - ret = io_init(&z->io, z->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + ret = io_init(&z->io, z->format, &n->in.signals, (int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET); if (ret) return ret; @@ -274,13 +274,13 @@ int zeromq_start(struct node *n) switch (z->pattern) { #ifdef ZMQ_BUILD_DISH - case zeromq::pattern::RADIODISH: + case zeromq::Pattern::RADIODISH: z->in.socket = zmq_socket(context, ZMQ_DISH); z->out.socket = zmq_socket(context, ZMQ_RADIO); break; #endif - case zeromq::pattern::PUBSUB: + case zeromq::Pattern::PUBSUB: z->in.socket = zmq_socket(context, ZMQ_SUB); z->out.socket = zmq_socket(context, ZMQ_PUB); break; @@ -294,12 +294,12 @@ int zeromq_start(struct node *n) /* Join group */ switch (z->pattern) { #ifdef ZMQ_BUILD_DISH - case zeromq::pattern::RADIODISH: + case zeromq::Pattern::RADIODISH: ret = zmq_join(z->in.socket, z->in.filter); break; #endif - case zeromq::pattern::PUBSUB: + case zeromq::Pattern::PUBSUB: ret = zmq_setsockopt(z->in.socket, ZMQ_SUBSCRIBE, z->in.filter, z->in.filter ? strlen(z->in.filter) : 0); break; @@ -459,7 +459,7 @@ int zeromq_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r if (z->in.filter) { switch (z->pattern) { - case zeromq::pattern::PUBSUB: + case zeromq::Pattern::PUBSUB: /* Discard envelope */ zmq_recv(z->in.socket, nullptr, 0, 0); break; @@ -501,14 +501,14 @@ int zeromq_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned * if (z->out.filter) { switch (z->pattern) { #ifdef ZMQ_BUILD_DISH - case zeromq::pattern::RADIODISH: + case zeromq::Pattern::RADIODISH: ret = zmq_msg_set_group(&m, z->out.filter); if (ret < 0) goto fail; break; #endif - case zeromq::pattern::PUBSUB: /* Send envelope */ + case zeromq::Pattern::PUBSUB: /* Send envelope */ zmq_send(z->out.socket, z->out.filter, strlen(z->out.filter), ZMQ_SNDMORE); break; } @@ -570,13 +570,13 @@ static struct plugin p; __attribute__((constructor(110))) static void register_plugin() { - if (plugins.state == STATE_DESTROYED) + if (plugins.state == State::DESTROYED) vlist_init(&plugins); p.name = "zeromq"; p.description = "ZeroMQ Distributed Messaging (libzmq)"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; + p.type = PluginType::NODE; + p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; p.node.size = sizeof(struct zeromq); p.node.type.start = zeromq_type_start; @@ -598,6 +598,6 @@ static void register_plugin() { __attribute__((destructor(110))) static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) + if (plugins.state != State::DESTROYED) vlist_remove_all(&plugins, &p); } diff --git a/lib/path.cpp b/lib/path.cpp index 7e70833d9..ed811799a 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -45,6 +45,7 @@ #include using namespace villas; +using namespace villas::node; using namespace villas::utils; static void * path_run_single(void *arg) @@ -53,7 +54,7 @@ static void * path_run_single(void *arg) struct path *p = (struct path *) arg; struct path_source *ps = (struct path_source *) vlist_at(&p->sources, 0); - while (p->state == STATE_STARTED) { + while (p->state == State::STARTED) { pthread_testcancel(); ret = path_source_read(ps, p, 0); @@ -76,7 +77,7 @@ static void * path_run_poll(void *arg) int ret; struct path *p = (struct path *) arg; - while (p->state == STATE_STARTED) { + while (p->state == State::STARTED) { ret = poll(p->reader.pfds, p->reader.nfds, -1); if (ret < 0) serror("Failed to poll"); @@ -115,7 +116,7 @@ int path_init(struct path *p) { int ret; - assert(p->state == STATE_DESTROYED); + assert(p->state == State::DESTROYED); new (&p->logger) Logger; new (&p->received) std::bitset; @@ -148,7 +149,7 @@ int path_init(struct path *p) p->_name = nullptr; /* Default values */ - p->mode = PATH_MODE_ANY; + p->mode = PathMode::ANY; p->rate = 0; /* Disabled */ p->builtin = 1; @@ -158,7 +159,7 @@ int path_init(struct path *p) p->queuelen = DEFAULT_QUEUE_LENGTH; p->original_sequence_no = -1; - p->state = STATE_INITIALIZED; + p->state = State::INITIALIZED; return 0; } @@ -216,7 +217,7 @@ int path_prepare(struct path *p) { int ret; - assert(p->state == STATE_CHECKED); + assert(p->state == State::CHECKED); /* Initialize destinations */ struct memory_type *pool_mt = &memory_hugepage; @@ -253,14 +254,14 @@ int path_prepare(struct path *p) for (size_t i = 0; i < vlist_length(&ps->mappings); i++) { struct mapping_entry *me = (struct mapping_entry *) vlist_at(&ps->mappings, i); - struct vlist *sigs = node_get_signals(me->node, NODE_DIR_IN); + struct vlist *sigs = node_get_signals(me->node, NodeDir::IN); for (unsigned j = 0; j < (unsigned) me->length; j++) { struct signal *sig; /* For data mappings we simple refer to the existing * signal descriptors of the source node. */ - if (me->type == MAPPING_TYPE_DATA) { + if (me->type == MappingType::DATA) { sig = (struct signal *) vlist_at_safe(sigs, me->data.offset + j); if (!sig) { p->logger->warn("Failed to create signal description for path {}", path_name(p)); @@ -285,7 +286,7 @@ int path_prepare(struct path *p) } #ifdef WITH_HOOKS - int m = p->builtin ? HOOK_PATH | HOOK_BUILTIN : 0; + int m = p->builtin ? (int) Hook::Flags::PATH | (int) Hook::Flags::BUILTIN : 0; /* Add internal hooks if they are not already in the list */ hook_list_prepare(&p->hooks, &p->signals, m, p, nullptr); @@ -306,7 +307,7 @@ int path_prepare(struct path *p) if (p->original_sequence_no == -1) p->original_sequence_no = vlist_length(&p->sources) == 1; - p->state = STATE_PREPARED; + p->state = State::PREPARED; return 0; } @@ -323,7 +324,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) const char *mode = nullptr; - struct vlist destinations = { .state = STATE_DESTROYED }; + struct vlist destinations = { .state = State::DESTROYED }; vlist_init(&destinations); @@ -354,9 +355,9 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) /* Optional settings */ if (mode) { if (!strcmp(mode, "any")) - p->mode = PATH_MODE_ANY; + p->mode = PathMode::ANY; else if (!strcmp(mode, "all")) - p->mode = PATH_MODE_ALL; + p->mode = PathMode::ALL; else { p->logger->error("Invalid path mode '{}'", mode); return -1; @@ -391,7 +392,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) ps->node = me->node; ps->masked = false; - ps->mappings.state = STATE_DESTROYED; + ps->mappings.state = State::DESTROYED; vlist_init(&ps->mappings); @@ -476,7 +477,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) #ifdef WITH_HOOKS if (json_hooks) { - hook_list_parse(&p->hooks, json_hooks, HOOK_PATH, p, nullptr); + hook_list_parse(&p->hooks, json_hooks, (int) Hook::Flags::PATH, p, nullptr); } #endif /* WITH_HOOKS */ @@ -495,14 +496,14 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes) return ret; p->cfg = cfg; - p->state = STATE_PARSED; + p->state = State::PARSED; return 0; } int path_check(struct path *p) { - assert(p->state != STATE_DESTROYED); + assert(p->state != State::DESTROYED); if (p->rate < 0) { p->logger->error("Setting 'rate' of path {} must be a positive number.", path_name(p)); @@ -559,7 +560,7 @@ int path_check(struct path *p) p->logger->warn("Queue length should always be a power of 2. Adjusting to {}", p->queuelen); } - p->state = STATE_CHECKED; + p->state = State::CHECKED; return 0; } @@ -569,14 +570,14 @@ int path_start(struct path *p) int ret; const char *mode; - assert(p->state == STATE_PREPARED); + assert(p->state == State::PREPARED); switch (p->mode) { - case PATH_MODE_ANY: + case PathMode::ANY: mode = "any"; break; - case PATH_MODE_ALL: + case PathMode::ALL: mode = "all"; break; @@ -619,7 +620,7 @@ int path_start(struct path *p) p->last_sample->length = 0; p->last_sample->signals = &p->signals; p->last_sample->sequence = 0; - p->last_sample->flags = p->last_sample->length > 0 ? SAMPLE_HAS_DATA : 0; + p->last_sample->flags = p->last_sample->length > 0 ? (int) SampleFlags::HAS_DATA : 0; for (size_t i = 0; i < p->last_sample->length; i++) { struct signal *sig = (struct signal *) vlist_at(p->last_sample->signals, i); @@ -637,7 +638,7 @@ int path_start(struct path *p) if (ret) return ret; - p->state = STATE_STARTED; + p->state = State::STARTED; return 0; } @@ -646,13 +647,13 @@ int path_stop(struct path *p) { int ret; - if (p->state != STATE_STARTED && p->state != STATE_STOPPING) + if (p->state != State::STARTED && p->state != State::STOPPING) return 0; p->logger->info("Stopping path: {}", path_name(p)); - if (p->state != STATE_STOPPING) - p->state = STATE_STOPPING; + if (p->state != State::STOPPING) + p->state = State::STOPPING; /* Cancel the thread in case is currently in a blocking syscall. * @@ -672,7 +673,7 @@ int path_stop(struct path *p) sample_decref(p->last_sample); - p->state = STATE_STOPPED; + p->state = State::STOPPED; return 0; } @@ -681,7 +682,7 @@ int path_destroy(struct path *p) { int ret; - if (p->state == STATE_DESTROYED) + if (p->state == State::DESTROYED) return 0; #ifdef WITH_HOOKS @@ -725,7 +726,7 @@ int path_destroy(struct path *p) p->mask.~bs(); p->logger.~lg(); - p->state = STATE_DESTROYED; + p->state = State::DESTROYED; return 0; } diff --git a/lib/path_source.cpp b/lib/path_source.cpp index 4a289ff14..bb63b953d 100644 --- a/lib/path_source.cpp +++ b/lib/path_source.cpp @@ -84,8 +84,8 @@ int path_source_read(struct path_source *ps, struct path *p, int i) goto out2; } else if (recv < 0) { - if (ps->node->state == STATE_STOPPING) { - p->state = STATE_STOPPING; + if (ps->node->state == State::STOPPING) { + p->state = State::STOPPING; enqueued = -1; goto out2; @@ -100,7 +100,7 @@ int path_source_read(struct path_source *ps, struct path *p, int i) p->received.set(i); - if (p->mode == PATH_MODE_ANY) { /* Mux all samples */ + if (p->mode == PathMode::ANY) { /* Mux all samples */ tomux_smps = read_smps; tomux = recv; } @@ -118,17 +118,17 @@ int path_source_read(struct path_source *ps, struct path *p, int i) muxed_smps[i]->sequence = tomux_smps[i]->sequence; else { muxed_smps[i]->sequence = p->last_sequence++; - muxed_smps[i]->flags |= SAMPLE_HAS_SEQUENCE; + muxed_smps[i]->flags |= (int) SampleFlags::HAS_SEQUENCE; } /* We reset the sample length after each restart of the simulation. * This is necessary for the test_rtt node to work properly. */ - if (tomux_smps[i]->flags & SAMPLE_IS_FIRST) + if (tomux_smps[i]->flags & (int) SampleFlags::IS_FIRST) muxed_smps[i]->length = 0; muxed_smps[i]->ts = tomux_smps[i]->ts; - muxed_smps[i]->flags |= tomux_smps[i]->flags & (SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_TS_RECEIVED); + muxed_smps[i]->flags |= tomux_smps[i]->flags & ((int) SampleFlags::HAS_TS_ORIGIN | (int) SampleFlags::HAS_TS_RECEIVED); ret = mapping_list_remap(&ps->mappings, muxed_smps[i], tomux_smps[i]); if (ret) @@ -152,8 +152,8 @@ int path_source_read(struct path_source *ps, struct path *p, int i) if (p->mask.test(i)) { /* Check if we received an update from all nodes */ - if ((p->mode == PATH_MODE_ANY) || - (p->mode == PATH_MODE_ALL && p->mask == p->received)) { + if ((p->mode == PathMode::ANY) || + (p->mode == PathMode::ALL && p->mask == p->received)) { path_destination_enqueue(p, muxed_smps, toenqueue); /* Reset mask of updated nodes */ diff --git a/lib/plugin.cpp b/lib/plugin.cpp index 6ddbaf6c3..1e1731b03 100644 --- a/lib/plugin.cpp +++ b/lib/plugin.cpp @@ -26,11 +26,11 @@ #include /** Global list of all known plugins */ -struct vlist plugins = { .state = STATE_DESTROYED }; +struct vlist plugins = { .state = State::DESTROYED }; LIST_INIT_STATIC(&plugins) -struct plugin * plugin_lookup(enum plugin_type type, const char *name) +struct plugin * plugin_lookup(enum PluginType type, const char *name) { for (size_t i = 0; i < vlist_length(&plugins); i++) { struct plugin *p = (struct plugin *) vlist_at(&plugins, i); @@ -42,7 +42,7 @@ struct plugin * plugin_lookup(enum plugin_type type, const char *name) return nullptr; } -void plugin_dump(enum plugin_type type) +void plugin_dump(enum PluginType type) { for (size_t i = 0; i < vlist_length(&plugins); i++) { struct plugin *p = (struct plugin *) vlist_at(&plugins, i); diff --git a/lib/pool.cpp b/lib/pool.cpp index bb4a0a8c3..cb10128a0 100644 --- a/lib/pool.cpp +++ b/lib/pool.cpp @@ -29,7 +29,7 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *m) { int ret; - assert(p->state == STATE_DESTROYED); + assert(p->state == State::DESTROYED); /* Make sure that we use a block size that is aligned to the size of a cache line */ p->alignment = kernel_get_cacheline_size(); @@ -51,7 +51,7 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *m) for (unsigned i = 0; i < cnt; i++) queue_push(&p->queue, (char *) buffer + i * p->blocksz); - p->state = STATE_INITIALIZED; + p->state = State::INITIALIZED; return 0; } @@ -60,7 +60,7 @@ int pool_destroy(struct pool *p) { int ret; - if (p->state == STATE_DESTROYED) + if (p->state == State::DESTROYED) return 0; queue_destroy(&p->queue); @@ -68,7 +68,7 @@ int pool_destroy(struct pool *p) void *buffer = (char *) p + p->buffer_off; ret = memory_free(buffer); if (ret == 0) - p->state = STATE_DESTROYED; + p->state = State::DESTROYED; return ret; } diff --git a/lib/queue.cpp b/lib/queue.cpp index 16c442c7c..2647acc3f 100644 --- a/lib/queue.cpp +++ b/lib/queue.cpp @@ -38,7 +38,7 @@ /** Initialize MPMC queue */ int queue_init(struct queue *q, size_t size, struct memory_type *m) { - assert(q->state == STATE_DESTROYED); + assert(q->state == State::DESTROYED); /* Queue size must be 2 exponent */ if (!IS_POW2(size)) { @@ -65,7 +65,7 @@ int queue_init(struct queue *q, size_t size, struct memory_type *m) std::atomic_store_explicit(&q->head, 0u, std::memory_order_relaxed); #endif - q->state = STATE_INITIALIZED; + q->state = State::INITIALIZED; return 0; } @@ -75,12 +75,12 @@ int queue_destroy(struct queue *q) void *buffer = (char *) q + q->buffer_off; int ret = 0; - if (q->state == STATE_DESTROYED) + if (q->state == State::DESTROYED) return 0; ret = memory_free(buffer); if (ret == 0) - q->state = STATE_DESTROYED; + q->state = State::DESTROYED; return ret; } @@ -97,7 +97,7 @@ int queue_push(struct queue *q, void *ptr) size_t pos, seq; intptr_t diff; - if (std::atomic_load_explicit(&q->state, std::memory_order_relaxed) == STATE_STOPPED) + if (std::atomic_load_explicit(&q->state, std::memory_order_relaxed) == State::STOPPED) return -1; buffer = (struct queue_cell *) ((char *) q + q->buffer_off); @@ -129,7 +129,7 @@ int queue_pull(struct queue *q, void **ptr) size_t pos, seq; intptr_t diff; - if (std::atomic_load_explicit(&q->state, std::memory_order_relaxed) == STATE_STOPPED) + if (std::atomic_load_explicit(&q->state, std::memory_order_relaxed) == State::STOPPED) return -1; buffer = (struct queue_cell *) ((char *) q + q->buffer_off); @@ -191,8 +191,8 @@ int queue_pull_many(struct queue *q, void *ptr[], size_t cnt) int queue_close(struct queue *q) { - enum state expected = STATE_INITIALIZED; - if (std::atomic_compare_exchange_weak_explicit(&q->state, &expected, STATE_STOPPED, std::memory_order_relaxed, std::memory_order_relaxed)) + enum State expected = State::INITIALIZED; + if (std::atomic_compare_exchange_weak_explicit(&q->state, &expected, State::STOPPED, std::memory_order_relaxed, std::memory_order_relaxed)) return 0; return -1; diff --git a/lib/queue_signalled.cpp b/lib/queue_signalled.cpp index d66b89cde..6599fb95c 100644 --- a/lib/queue_signalled.cpp +++ b/lib/queue_signalled.cpp @@ -33,34 +33,34 @@ static void queue_signalled_cleanup(void *p) { struct queue_signalled *qs = (struct queue_signalled *) p; - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_mutex_unlock(&qs->pthread.mutex); } -int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_type *mem, int flags) +int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_type *mem, enum QueueSignalledMode mode, int flags) { int ret; - qs->mode = (enum queue_signalled_flags) (flags & QUEUE_SIGNALLED_MASK); + qs->mode = mode; - if (qs->mode == 0) { + if (qs->mode == QueueSignalledMode::AUTO) { #ifdef __linux__ - if (flags & QUEUE_SIGNALLED_PROCESS_SHARED) - qs->mode = QUEUE_SIGNALLED_PTHREAD; + if (flags & (int) QueueSignalledFlags::PROCESS_SHARED) + qs->mode = QueueSignalledMode::PTHREAD; else { #ifdef HAS_EVENTFD - qs->mode = QUEUE_SIGNALLED_EVENTFD; + qs->mode = QueueSignalledMode::EVENTFD; #else - qs->mode = QUEUE_SIGNALLED_PTHREAD; + qs->mode = QueueSignalledMode::PTHREAD; #endif } #elif defined(__APPLE__) - if (flags & QUEUE_SIGNALLED_PROCESS_SHARED) - qs->mode = QUEUE_SIGNALLED_PTHREAD; + if (flags & (int) QueueSignalledFlags::PROCESS_SHARED) + qs->mode = QueueSignalledMode::PTHREAD; else - qs->mode = QUEUE_SIGNALLED_PIPE; + qs->mode = QueueSignalledMode::PIPE; #else - qs->mode = QUEUE_SIGNALLED_PTHREAD; + qs->mode = QueueSignalledMode::PTHREAD; #endif } @@ -68,14 +68,14 @@ int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_ if (ret < 0) return ret; - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) { + if (qs->mode == QueueSignalledMode::PTHREAD) { pthread_condattr_t cvattr; pthread_mutexattr_t mtattr; pthread_mutexattr_init(&mtattr); pthread_condattr_init(&cvattr); - if (flags & QUEUE_SIGNALLED_PROCESS_SHARED) { + if (flags & (int) QueueSignalledFlags::PROCESS_SHARED) { pthread_mutexattr_setpshared(&mtattr, PTHREAD_PROCESS_SHARED); pthread_condattr_setpshared(&cvattr, PTHREAD_PROCESS_SHARED); } @@ -86,17 +86,17 @@ int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_ pthread_mutexattr_destroy(&mtattr); pthread_condattr_destroy(&cvattr); } - else if (qs->mode == QUEUE_SIGNALLED_POLLING) { + else if (qs->mode == QueueSignalledMode::POLLING) { /* Nothing todo */ } #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { qs->eventfd = eventfd(0, 0); if (qs->eventfd < 0) return -2; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { ret = pipe(qs->pipe); if (ret < 0) return -2; @@ -116,21 +116,21 @@ int queue_signalled_destroy(struct queue_signalled *qs) if (ret < 0) return ret; - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) { + if (qs->mode == QueueSignalledMode::PTHREAD) { pthread_cond_destroy(&qs->pthread.ready); pthread_mutex_destroy(&qs->pthread.mutex); } - else if (qs->mode == QUEUE_SIGNALLED_POLLING) { + else if (qs->mode == QueueSignalledMode::POLLING) { /* Nothing todo */ } #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { ret = close(qs->eventfd); if (ret) return ret; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { ret = close(qs->pipe[0]) + close(qs->pipe[1]); if (ret) return ret; @@ -150,16 +150,16 @@ int queue_signalled_push(struct queue_signalled *qs, void *ptr) if (pushed < 0) return pushed; - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) { + if (qs->mode == QueueSignalledMode::PTHREAD) { pthread_mutex_lock(&qs->pthread.mutex); pthread_cond_broadcast(&qs->pthread.ready); pthread_mutex_unlock(&qs->pthread.mutex); } - else if (qs->mode == QUEUE_SIGNALLED_POLLING) { + else if (qs->mode == QueueSignalledMode::POLLING) { /* Nothing todo */ } #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { int ret; uint64_t incr = 1; ret = write(qs->eventfd, &incr, sizeof(incr)); @@ -167,7 +167,7 @@ int queue_signalled_push(struct queue_signalled *qs, void *ptr) return ret; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { int ret; uint8_t incr = 1; ret = write(qs->pipe[1], &incr, sizeof(incr)); @@ -189,16 +189,16 @@ int queue_signalled_push_many(struct queue_signalled *qs, void *ptr[], size_t cn if (pushed < 0) return pushed; - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) { + if (qs->mode == QueueSignalledMode::PTHREAD) { pthread_mutex_lock(&qs->pthread.mutex); pthread_cond_broadcast(&qs->pthread.ready); pthread_mutex_unlock(&qs->pthread.mutex); } - else if (qs->mode == QUEUE_SIGNALLED_POLLING) { + else if (qs->mode == QueueSignalledMode::POLLING) { /* Nothing todo */ } #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { int ret; uint64_t incr = 1; ret = write(qs->eventfd, &incr, sizeof(incr)); @@ -206,7 +206,7 @@ int queue_signalled_push_many(struct queue_signalled *qs, void *ptr[], size_t cn return ret; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { int ret; uint8_t incr = 1; ret = write(qs->pipe[1], &incr, sizeof(incr)); @@ -227,7 +227,7 @@ int queue_signalled_pull(struct queue_signalled *qs, void **ptr) /* Make sure that qs->mutex is unlocked if this thread gets cancelled. */ pthread_cleanup_push(queue_signalled_cleanup, qs); - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_mutex_lock(&qs->pthread.mutex); while (!pulled) { @@ -235,12 +235,12 @@ int queue_signalled_pull(struct queue_signalled *qs, void **ptr) if (pulled < 0) break; else if (pulled == 0) { - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_cond_wait(&qs->pthread.ready, &qs->pthread.mutex); - else if (qs->mode == QUEUE_SIGNALLED_POLLING) + else if (qs->mode == QueueSignalledMode::POLLING) continue; /* Try again */ #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { int ret; uint64_t cntr; ret = read(qs->eventfd, &cntr, sizeof(cntr)); @@ -248,7 +248,7 @@ int queue_signalled_pull(struct queue_signalled *qs, void **ptr) break; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { int ret; uint8_t incr = 1; ret = read(qs->pipe[0], &incr, sizeof(incr)); @@ -261,7 +261,7 @@ int queue_signalled_pull(struct queue_signalled *qs, void **ptr) } } - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_mutex_unlock(&qs->pthread.mutex); pthread_cleanup_pop(0); @@ -276,7 +276,7 @@ int queue_signalled_pull_many(struct queue_signalled *qs, void *ptr[], size_t cn /* Make sure that qs->mutex is unlocked if this thread gets cancelled. */ pthread_cleanup_push(queue_signalled_cleanup, qs); - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_mutex_lock(&qs->pthread.mutex); while (!pulled) { @@ -284,12 +284,12 @@ int queue_signalled_pull_many(struct queue_signalled *qs, void *ptr[], size_t cn if (pulled < 0) break; else if (pulled == 0) { - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_cond_wait(&qs->pthread.ready, &qs->pthread.mutex); - else if (qs->mode == QUEUE_SIGNALLED_POLLING) + else if (qs->mode == QueueSignalledMode::POLLING) continue; /* Try again */ #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { int ret; uint64_t cntr; ret = read(qs->eventfd, &cntr, sizeof(cntr)); @@ -297,7 +297,7 @@ int queue_signalled_pull_many(struct queue_signalled *qs, void *ptr[], size_t cn break; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { int ret; uint8_t incr = 1; ret = read(qs->pipe[0], &incr, sizeof(incr)); @@ -310,7 +310,7 @@ int queue_signalled_pull_many(struct queue_signalled *qs, void *ptr[], size_t cn } } - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_mutex_unlock(&qs->pthread.mutex); pthread_cleanup_pop(0); @@ -322,20 +322,20 @@ int queue_signalled_close(struct queue_signalled *qs) { int ret; - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) + if (qs->mode == QueueSignalledMode::PTHREAD) pthread_mutex_lock(&qs->pthread.mutex); ret = queue_close(&qs->queue); - if (qs->mode == QUEUE_SIGNALLED_PTHREAD) { + if (qs->mode == QueueSignalledMode::PTHREAD) { pthread_cond_broadcast(&qs->pthread.ready); pthread_mutex_unlock(&qs->pthread.mutex); } - else if (qs->mode == QUEUE_SIGNALLED_POLLING) { + else if (qs->mode == QueueSignalledMode::POLLING) { /* Nothing todo */ } #ifdef HAS_EVENTFD - else if (qs->mode == QUEUE_SIGNALLED_EVENTFD) { + else if (qs->mode == QueueSignalledMode::EVENTFD) { int ret; uint64_t incr = 1; @@ -344,7 +344,7 @@ int queue_signalled_close(struct queue_signalled *qs) return ret; } #elif defined(__APPLE__) - else if (qs->mode == QUEUE_SIGNALLED_PIPE) { + else if (qs->mode == QueueSignalledMode::PIPE) { int ret; uint64_t incr = 1; @@ -363,10 +363,10 @@ int queue_signalled_fd(struct queue_signalled *qs) { switch (qs->mode) { #ifdef HAS_EVENTFD - case QUEUE_SIGNALLED_EVENTFD: + case QueueSignalledMode::EVENTFD: return qs->eventfd; #elif defined(__APPLE__) - case QUEUE_SIGNALLED_PIPE: + case QueueSignalledMode::PIPE: return qs->pipe[0]; #endif default: { } diff --git a/lib/sample.cpp b/lib/sample.cpp index c75ff03c1..ecbf83325 100644 --- a/lib/sample.cpp +++ b/lib/sample.cpp @@ -215,7 +215,7 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags) } /* Compare sequence no */ - if (flags & SAMPLE_HAS_SEQUENCE) { + if (flags & (int) SampleFlags::HAS_SEQUENCE) { if (a->sequence != b->sequence) { printf("sequence no: %" PRIu64 " != %" PRIu64 "\n", a->sequence, b->sequence); return 2; @@ -223,7 +223,7 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags) } /* Compare timestamp */ - if (flags & SAMPLE_HAS_TS_ORIGIN) { + if (flags & (int) SampleFlags::HAS_TS_ORIGIN) { if (time_delta(&a->ts.origin, &b->ts.origin) > epsilon) { printf("ts.origin: %f != %f\n", time_to_double(&a->ts.origin), time_to_double(&b->ts.origin)); return 3; @@ -231,7 +231,7 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags) } /* Compare data */ - if (flags & SAMPLE_HAS_DATA) { + if (flags & (int) SampleFlags::HAS_DATA) { if (a->length != b->length) { printf("length: %d != %d\n", a->length, b->length); return 4; @@ -243,28 +243,28 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags) return 6; switch (sample_format(a, i)) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: if (fabs(a->data[i].f - b->data[i].f) > epsilon) { printf("data[%d].f: %f != %f\n", i, a->data[i].f, b->data[i].f); return 5; } break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: if (a->data[i].i != b->data[i].i) { printf("data[%d].i: %" PRId64 " != %" PRId64 "\n", i, a->data[i].i, b->data[i].i); return 5; } break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: if (a->data[i].b != b->data[i].b) { printf("data[%d].b: %s != %s\n", i, a->data[i].b ? "true" : "false", b->data[i].b ? "true" : "false"); return 5; } break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: if (cabs(a->data[i].z - b->data[i].z) > epsilon) { printf("data[%d].z: %f+%fi != %f+%fi\n", i, creal(a->data[i].z), cimag(a->data[i].z), creal(b->data[i].z), cimag(b->data[i].z)); return 5; @@ -279,13 +279,13 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags) return 0; } -enum signal_type sample_format(const struct sample *s, unsigned idx) +enum SignalType sample_format(const struct sample *s, unsigned idx) { struct signal *sig; sig = (struct signal *) vlist_at_safe(s->signals, idx); - return sig ? sig->type : SIGNAL_TYPE_INVALID; + return sig ? sig->type : SignalType::INVALID; } void sample_dump(struct sample *s) @@ -295,10 +295,10 @@ void sample_dump(struct sample *s) s->sequence, s->length, s->capacity, s->flags, s->signals, s->signals ? vlist_length(s->signals) : 0, atomic_load(&s->refcnt), s->pool_off); - if (s->flags & SAMPLE_HAS_TS_ORIGIN) + if (s->flags & (int) SampleFlags::HAS_TS_ORIGIN) debug(5, " ts.origin=%ld.%ld", s->ts.origin.tv_sec, s->ts.origin.tv_nsec); - if (s->flags & SAMPLE_HAS_TS_RECEIVED) + if (s->flags & (int) SampleFlags::HAS_TS_RECEIVED) debug(5, " ts.received=%ld.%ld", s->ts.received.tv_sec, s->ts.received.tv_nsec); if (s->signals) diff --git a/lib/shmem.cpp b/lib/shmem.cpp index 32742269c..6883f1599 100644 --- a/lib/shmem.cpp +++ b/lib/shmem.cpp @@ -102,20 +102,19 @@ retry: fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600); shared->polling = conf->polling; - int flags = QUEUE_SIGNALLED_PROCESS_SHARED; - if (conf->polling) - flags |= QUEUE_SIGNALLED_POLLING; - else - flags |= QUEUE_SIGNALLED_PTHREAD; + int flags = (int) QueueSignalledFlags::PROCESS_SHARED; + enum QueueSignalledMode mode = conf->polling + ? QueueSignalledMode::POLLING + : QueueSignalledMode::PTHREAD; - shared->queue.queue.state = STATE_DESTROYED; - ret = queue_signalled_init(&shared->queue, conf->queuelen, manager, flags); + shared->queue.queue.state = State::DESTROYED; + ret = queue_signalled_init(&shared->queue, conf->queuelen, manager, mode, flags); if (ret) { errno = ENOMEM; return -6; } - shared->pool.state = STATE_DESTROYED; + shared->pool.state = State::DESTROYED; ret = pool_init(&shared->pool, conf->queuelen, SAMPLE_LENGTH(conf->samplelen), manager); if (ret) { errno = ENOMEM; diff --git a/lib/signal.cpp b/lib/signal.cpp index 2b42a775d..dcdd4a54f 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -37,7 +37,7 @@ int signal_init(struct signal *s) s->name = nullptr; s->unit = nullptr; - s->type = SIGNAL_TYPE_INVALID; + s->type = SignalType::INVALID; s->refcnt = ATOMIC_VAR_INIT(1); @@ -57,24 +57,24 @@ int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, u return ret; switch (me->type) { - case MAPPING_TYPE_STATS: + case MappingType::STATS: s->type = Stats::types[me->stats.type].signal_type; break; - case MAPPING_TYPE_HEADER: + case MappingType::HEADER: switch (me->header.type) { - case MAPPING_HEADER_TYPE_LENGTH: - case MAPPING_HEADER_TYPE_SEQUENCE: - s->type = SIGNAL_TYPE_INTEGER; + case MappingHeaderType::LENGTH: + case MappingHeaderType::SEQUENCE: + s->type = SignalType::INTEGER; break; } break; - case MAPPING_TYPE_TIMESTAMP: - s->type = SIGNAL_TYPE_INTEGER; + case MappingType::TIMESTAMP: + s->type = SignalType::INTEGER; break; - case MAPPING_TYPE_DATA: + case MappingType::DATA: s->type = me->data.signal->type; s->init = me->data.signal->init; s->enabled = me->data.signal->enabled; @@ -101,7 +101,7 @@ int signal_destroy(struct signal *s) return 0; } -struct signal * signal_create(const char *name, const char *unit, enum signal_type fmt) +struct signal * signal_create(const char *name, const char *unit, enum SignalType fmt) { int ret; struct signal *sig; @@ -204,7 +204,7 @@ int signal_parse(struct signal *s, json_t *cfg) if (type) { s->type = signal_type_from_str(type); - if (s->type == SIGNAL_TYPE_INVALID) + if (s->type == SignalType::INVALID) return -1; } @@ -272,7 +272,7 @@ int signal_list_parse(struct vlist *list, json_t *cfg) return 0; } -int signal_list_generate(struct vlist *list, unsigned len, enum signal_type typ) +int signal_list_generate(struct vlist *list, unsigned len, enum SignalType typ) { char name[32]; @@ -293,7 +293,7 @@ int signal_list_generate2(struct vlist *list, const char *dt) { int len, i = 0; char name[32], *e; - enum signal_type typ; + enum SignalType typ; for (const char *t = dt; *t; t = e + 1) { len = strtoul(t, &e, 10); @@ -301,7 +301,7 @@ int signal_list_generate2(struct vlist *list, const char *dt) len = 1; typ = signal_type_from_fmtstr(*e); - if (typ == SIGNAL_TYPE_INVALID) + if (typ == SignalType::INVALID) return -1; for (int j = 0; j < len; j++) { @@ -350,8 +350,8 @@ void signal_list_dump(const struct vlist *list, const union signal_data *data, u int signal_list_copy(struct vlist *dst, const struct vlist *src) { - assert(src->state == STATE_INITIALIZED); - assert(dst->state == STATE_INITIALIZED); + assert(src->state == State::INITIALIZED); + assert(dst->state == State::INITIALIZED); for (size_t i = 0; i < vlist_length(src); i++) { struct signal *s = (struct signal *) vlist_at_safe(src, i); @@ -366,63 +366,63 @@ int signal_list_copy(struct vlist *dst, const struct vlist *src) /* Signal type */ -enum signal_type signal_type_from_str(const char *str) +enum SignalType signal_type_from_str(const char *str) { if (!strcmp(str, "boolean")) - return SIGNAL_TYPE_BOOLEAN; + return SignalType::BOOLEAN; else if (!strcmp(str, "complex")) - return SIGNAL_TYPE_COMPLEX; + return SignalType::COMPLEX; else if (!strcmp(str, "float")) - return SIGNAL_TYPE_FLOAT; + return SignalType::FLOAT; else if (!strcmp(str, "integer")) - return SIGNAL_TYPE_INTEGER; + return SignalType::INTEGER; else - return SIGNAL_TYPE_INVALID; + return SignalType::INVALID; } -enum signal_type signal_type_from_fmtstr(char c) +enum SignalType signal_type_from_fmtstr(char c) { switch (c) { case 'f': - return SIGNAL_TYPE_FLOAT; + return SignalType::FLOAT; case 'i': - return SIGNAL_TYPE_INTEGER; + return SignalType::INTEGER; case 'c': - return SIGNAL_TYPE_COMPLEX; + return SignalType::COMPLEX; case 'b': - return SIGNAL_TYPE_BOOLEAN; + return SignalType::BOOLEAN; default: - return SIGNAL_TYPE_INVALID; + return SignalType::INVALID; } } -const char * signal_type_to_str(enum signal_type fmt) +const char * signal_type_to_str(enum SignalType fmt) { switch (fmt) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: return "boolean"; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: return "complex"; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: return "float"; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: return "integer"; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: return "invalid"; } return nullptr; } -enum signal_type signal_type_detect(const char *val) +enum SignalType signal_type_detect(const char *val) { const char *brk; int len; @@ -431,17 +431,17 @@ enum signal_type signal_type_detect(const char *val) brk = strchr(val, 'i'); if (brk) - return SIGNAL_TYPE_COMPLEX; + return SignalType::COMPLEX; brk = strchr(val, '.'); if (brk) - return SIGNAL_TYPE_FLOAT; + return SignalType::FLOAT; len = strlen(val); if (len == 1 && (val[0] == '1' || val[0] == '0')) - return SIGNAL_TYPE_BOOLEAN; + return SignalType::BOOLEAN; - return SIGNAL_TYPE_INTEGER; + return SignalType::INTEGER; } /* Signal data */ @@ -449,23 +449,23 @@ enum signal_type signal_type_detect(const char *val) void signal_data_set(union signal_data *data, const struct signal *sig, double val) { switch (sig->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->b = val; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->f = val; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->i = val; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: data->z = val; break; - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: memset(data, 0, sizeof(union signal_data)); break; } @@ -477,21 +477,21 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const return; switch (to->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: switch(from->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->b = data->b; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->b = data->i; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->b = data->f; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: data->b = creal(data->z); break; @@ -499,21 +499,21 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const } break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: switch(from->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->i = data->b; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->i = data->i; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->i = data->f; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: data->i = creal(data->z); break; @@ -521,21 +521,21 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const } break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: switch(from->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->f = data->b; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->f = data->i; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->f = data->f; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: data->f = creal(data->z); break; @@ -543,21 +543,21 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const } break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: switch(from->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->z = data->b; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->z = data->i; break; - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->z = data->f; break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: data->z = data->z; break; @@ -572,19 +572,19 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const int signal_data_parse_str(union signal_data *data, const struct signal *sig, const char *ptr, char **end) { switch (sig->type) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->f = strtod(ptr, end); break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->i = strtol(ptr, end, 10); break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->b = strtol(ptr, end, 10); break; - case SIGNAL_TYPE_COMPLEX: { + case SignalType::COMPLEX: { float real, imag; real = strtod(ptr, end); @@ -606,7 +606,7 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con break; } - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: return -1; } @@ -618,19 +618,19 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js int ret; switch (sig->type) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->f = json_real_value(cfg); break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->i = json_integer_value(cfg); break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->b = json_boolean_value(cfg); break; - case SIGNAL_TYPE_COMPLEX: { + case SignalType::COMPLEX: { double real, imag; json_error_t err; @@ -645,7 +645,7 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js break; } - case SIGNAL_TYPE_INVALID: + case SignalType::INVALID: return -1; } @@ -655,16 +655,16 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js int signal_data_snprint(const union signal_data *data, const struct signal *sig, char *buf, size_t len) { switch (sig->type) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: return snprintf(buf, len, "%.6f", data->f); - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: return snprintf(buf, len, "%" PRIi64, data->i); - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: return snprintf(buf, len, "%u", data->b); - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: return snprintf(buf, len, "%.6f%+.6fi", creal(data->z), cimag(data->z)); default: diff --git a/lib/socket_addr.cpp b/lib/socket_addr.cpp index af293f768..d4bfbc09d 100644 --- a/lib/socket_addr.cpp +++ b/lib/socket_addr.cpp @@ -85,7 +85,7 @@ char * socket_print_addr(struct sockaddr *saddr) return buf; } -int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_layer layer, int flags) +int socket_parse_address(const char *addr, struct sockaddr *saddr, enum SocketLayer layer, int flags) { /** @todo: Add support for IPv6 */ union sockaddr_union *sa = (union sockaddr_union *) saddr; @@ -93,7 +93,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l char *copy = strdup(addr); int ret; - if (layer == SOCKET_LAYER_UNIX) { /* Format: "/path/to/socket" */ + if (layer == SocketLayer::UNIX) { /* Format: "/path/to/socket" */ sa->sun.sun_family = AF_UNIX; if (strlen(addr) > sizeof(sa->sun.sun_path) - 1) @@ -104,7 +104,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l ret = 0; } #ifdef WITH_SOCKET_LAYER_ETH - else if (layer == SOCKET_LAYER_ETH) { /* Format: "ab:cd:ef:12:34:56%ifname:protocol" */ + else if (layer == SocketLayer::ETH) { /* Format: "ab:cd:ef:12:34:56%ifname:protocol" */ /* Split string */ char *lasts; char *node = strtok_r(copy, "%", &lasts); @@ -151,13 +151,13 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l service = nullptr; switch (layer) { - case SOCKET_LAYER_IP: + case SocketLayer::IP: hint.ai_socktype = SOCK_RAW; hint.ai_protocol = (service) ? strtol(service, nullptr, 0) : IPPROTO_VILLAS; hint.ai_flags |= AI_NUMERICSERV; break; - case SOCKET_LAYER_UDP: + case SocketLayer::UDP: hint.ai_socktype = SOCK_DGRAM; hint.ai_protocol = IPPROTO_UDP; break; @@ -168,9 +168,9 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l /* Lookup address */ struct addrinfo *result; - ret = getaddrinfo(node, (layer == SOCKET_LAYER_IP) ? nullptr : service, &hint, &result); + ret = getaddrinfo(node, (layer == SocketLayer::IP) ? nullptr : service, &hint, &result); if (!ret) { - if (layer == SOCKET_LAYER_IP) { + if (layer == SocketLayer::IP) { /* We mis-use the sin_port field to store the IP protocol number on RAW sockets */ struct sockaddr_in *sin = (struct sockaddr_in *) result->ai_addr; sin->sin_port = htons(result->ai_protocol); diff --git a/lib/stats.cpp b/lib/stats.cpp index 557772bc9..a00220783 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -47,13 +47,13 @@ std::unordered_map Stats::metrics = { }; std::unordered_map Stats::types = { - { Stats::Type::LAST, { "last", SIGNAL_TYPE_FLOAT }}, - { Stats::Type::HIGHEST, { "highest", SIGNAL_TYPE_FLOAT }}, - { Stats::Type::LOWEST, { "lowest", SIGNAL_TYPE_FLOAT }}, - { Stats::Type::MEAN, { "mean", SIGNAL_TYPE_FLOAT }}, - { Stats::Type::VAR, { "var", SIGNAL_TYPE_FLOAT }}, - { Stats::Type::STDDEV, { "stddev", SIGNAL_TYPE_FLOAT }}, - { Stats::Type::TOTAL, { "total", SIGNAL_TYPE_INTEGER }} + { Stats::Type::LAST, { "last", SignalType::FLOAT }}, + { Stats::Type::HIGHEST, { "highest", SignalType::FLOAT }}, + { Stats::Type::LOWEST, { "lowest", SignalType::FLOAT }}, + { Stats::Type::MEAN, { "mean", SignalType::FLOAT }}, + { Stats::Type::VAR, { "var", SignalType::FLOAT }}, + { Stats::Type::STDDEV, { "stddev", SignalType::FLOAT }}, + { Stats::Type::TOTAL, { "total", SignalType::INTEGER }} }; std::vector Stats::columns = { diff --git a/lib/super_node.cpp b/lib/super_node.cpp index c9b55917c..9d4731385 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -47,7 +47,7 @@ using namespace villas::node; using namespace villas::utils; SuperNode::SuperNode() : - state(STATE_INITIALIZED), + state(State::INITIALIZED), idleStop(false), #ifdef WITH_API api(this), @@ -63,9 +63,9 @@ SuperNode::SuperNode() : affinity(0), hugepages(DEFAULT_NR_HUGEPAGES) { - nodes.state = STATE_DESTROYED; - paths.state = STATE_DESTROYED; - interfaces.state = STATE_DESTROYED; + nodes.state = State::DESTROYED; + paths.state = State::DESTROYED; + interfaces.state = State::DESTROYED; vlist_init(&nodes); vlist_init(&paths); @@ -95,7 +95,7 @@ void SuperNode::parse(json_t *cfg) int ret; const char *nme = nullptr; - assert(state != STATE_STARTED); + assert(state != State::STARTED); json_t *json_nodes = nullptr; json_t *json_paths = nullptr; @@ -215,14 +215,14 @@ parse: path *p = (path *) alloc(sizeof(path)); } } - state = STATE_PARSED; + state = State::PARSED; } void SuperNode::check() { int ret; - assert(state == STATE_INITIALIZED || state == STATE_PARSED || state == STATE_CHECKED); + assert(state == State::INITIALIZED || state == State::PARSED || state == State::CHECKED); for (size_t i = 0; i < vlist_length(&nodes); i++) { auto *n = (struct node *) vlist_at(&nodes, i); @@ -240,7 +240,7 @@ void SuperNode::check() throw RuntimeError("Invalid configuration for path {}", path_name(p)); } - state = STATE_CHECKED; + state = State::CHECKED; } void SuperNode::startNodeTypes() @@ -345,7 +345,7 @@ void SuperNode::prepare() { int ret; - assert(state == STATE_CHECKED); + assert(state == State::CHECKED); ret = memory_init(hugepages); if (ret) @@ -356,14 +356,14 @@ void SuperNode::prepare() prepareNodes(); preparePaths(); - state = STATE_PREPARED; + state = State::PREPARED; } void SuperNode::start() { int ret; - assert(state == STATE_PREPARED); + assert(state == State::PREPARED); #ifdef WITH_API api.start(); @@ -384,7 +384,7 @@ void SuperNode::start() Stats::printHeader(Stats::Format::HUMAN); - state = STATE_STARTED; + state = State::STARTED; } void SuperNode::stopPaths() @@ -420,7 +420,7 @@ void SuperNode::stopNodeTypes() for (size_t i = 0; i < vlist_length(&plugins); i++) { auto *p = (struct plugin *) vlist_at(&plugins, i); - if (p->type == PLUGIN_TYPE_NODE) { + if (p->type == PluginType::NODE) { ret = node_type_stop(&p->node); if (ret) throw RuntimeError("Failed to stop node-type: {}", node_type_name(&p->node)); @@ -464,25 +464,25 @@ void SuperNode::stop() web.stop(); #endif - state = STATE_STOPPED; + state = State::STOPPED; } void SuperNode::run() { int ret; - while (state == STATE_STARTED) { + while (state == State::STARTED) { task_wait(&task); ret = periodic(); if (ret) - state = STATE_STOPPING; + state = State::STOPPING; } } SuperNode::~SuperNode() { - assert(state != STATE_STARTED); + assert(state != State::STARTED); vlist_destroy(&paths, (dtor_cb_t) path_destroy, true); vlist_destroy(&nodes, (dtor_cb_t) node_destroy, true); @@ -496,7 +496,7 @@ int SuperNode::periodic() for (size_t i = 0; i < vlist_length(&paths); i++) { auto *p = (struct path *) vlist_at(&paths, i); - if (p->state == STATE_STARTED) { + if (p->state == State::STARTED) { started++; #ifdef WITH_HOOKS @@ -508,7 +508,7 @@ int SuperNode::periodic() for (size_t i = 0; i < vlist_length(&nodes); i++) { auto *n = (struct node *) vlist_at(&nodes, i); - if (n->state == STATE_STARTED) { + if (n->state == State::STARTED) { #ifdef WITH_HOOKS hook_list_periodic(&n->in.hooks); hook_list_periodic(&n->out.hooks); @@ -516,7 +516,7 @@ int SuperNode::periodic() } } - if (idleStop && state == STATE_STARTED && started == 0) { + if (idleStop && state == State::STARTED && started == 0) { info("No more active paths. Stopping super-node"); return -1; diff --git a/lib/web.cpp b/lib/web.cpp index ca4478c17..950d609bd 100644 --- a/lib/web.cpp +++ b/lib/web.cpp @@ -183,7 +183,7 @@ void Web::worker() } Web::Web(Api *a) : - state(STATE_INITIALIZED), + state(State::INITIALIZED), htdocs(WEB_PATH), api(a) { @@ -229,7 +229,7 @@ int Web::parse(json_t *cfg) if (!enabled) port = CONTEXT_PORT_NO_LISTEN; - state = STATE_PARSED; + state = State::PARSED; return 0; } @@ -281,12 +281,12 @@ void Web::start() running = true; thread = std::thread(&Web::worker, this); - state = STATE_STARTED; + state = State::STARTED; } void Web::stop() { - assert(state == STATE_STARTED); + assert(state == State::STARTED); logger->info("Stopping sub-system"); @@ -295,7 +295,7 @@ void Web::stop() lws_context_destroy(context); - state = STATE_STOPPED; + state = State::STOPPED; } void Web::callbackOnWritable(lws *wsi) diff --git a/plugins/example_hook.cpp b/plugins/example_hook.cpp index d9f8162ef..0cb9659e3 100644 --- a/plugins/example_hook.cpp +++ b/plugins/example_hook.cpp @@ -41,7 +41,7 @@ public: static HookPlugin p( "example", "This is just a simple example hook", - HOOK_PATH, + (int) Hook::Flags::PATH, 99 ); diff --git a/src/villas-convert.cpp b/src/villas-convert.cpp index 29e467ebb..2fe387e93 100644 --- a/src/villas-convert.cpp +++ b/src/villas-convert.cpp @@ -55,7 +55,7 @@ public: for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) { dirs[i].format = "villas.human"; - dirs[i].io.state = STATE_DESTROYED; + dirs[i].io.state = State::DESTROYED; } } @@ -132,7 +132,7 @@ protected: if (!ft) throw RuntimeError("Invalid format: {}", dirs[i].format); - ret = io_init2(&dirs[i].io, ft, dtypes.c_str(), SAMPLE_HAS_ALL); + ret = io_init2(&dirs[i].io, ft, dtypes.c_str(), (int) SampleFlags::HAS_ALL); if (ret) throw RuntimeError("Failed to initialize IO: {}", dirs[i].name); diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index 0d80445c3..95f29c207 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -70,8 +70,8 @@ public: if (ret) throw RuntimeError("Failed to initialize memory"); - p.state = STATE_DESTROYED; - io.state = STATE_DESTROYED; + p.state = State::DESTROYED; + io.state = State::DESTROYED; cfg_cli = json_object(); } @@ -123,7 +123,7 @@ protected: #endif /* WITH_HOOKS */ std::cout << "Supported IO formats:" << std::endl; - plugin_dump(PLUGIN_TYPE_FORMAT); + plugin_dump(PluginType::FORMAT); std::cout << std::endl; std::cout << "Example:" << std::endl @@ -210,7 +210,7 @@ check: if (optarg == endptr) if (!ft) throw RuntimeError("Unknown IO format '{}'", format); - ret = io_init2(&io, ft, dtypes.c_str(), SAMPLE_HAS_ALL); + ret = io_init2(&io, ft, dtypes.c_str(), (int) SampleFlags::HAS_ALL); if (ret) throw RuntimeError("Failed to initialize IO"); @@ -257,24 +257,26 @@ check: if (optarg == endptr) for (int processed = 0; processed < recv; processed++) { struct sample *smp = smps[processed]; - if (!(smp->flags & SAMPLE_HAS_TS_RECEIVED)){ + if (!(smp->flags & (int) SampleFlags::HAS_TS_RECEIVED)){ smp->ts.received = now; - smp->flags |= SAMPLE_HAS_TS_RECEIVED; + smp->flags |= (int) SampleFlags::HAS_TS_RECEIVED; } - ret = h->process(smp); + auto ret = h->process(smp); switch (ret) { - case HOOK_ERROR: + using Reason = villas::node::Hook::Reason; + + case Reason::ERROR: throw RuntimeError("Failed to process samples"); - case HOOK_OK: + case Reason::OK: smps[send++] = smp; break; - case HOOK_SKIP_SAMPLE: + case Reason::SKIP_SAMPLE: break; - case HOOK_STOP_PROCESSING: + case Reason::STOP_PROCESSING: goto stop; } } diff --git a/src/villas-node.cpp b/src/villas-node.cpp index 2de248b35..295f42c68 100644 --- a/src/villas-node.cpp +++ b/src/villas-node.cpp @@ -88,7 +88,7 @@ protected: logger->info("Received {} signal. Terminating...", strsignal(signal)); } - sn.setState(STATE_STOPPING); + sn.setState(State::STOPPING); } void usage() @@ -108,7 +108,7 @@ protected: #endif /* ENABLE_OPAL_ASYNC */ << "Supported node-types:" << std::endl; - plugin_dump(PLUGIN_TYPE_NODE); + plugin_dump(PluginType::NODE); std::cout << std::endl; #ifdef WITH_HOOKS @@ -126,7 +126,7 @@ protected: #endif /* WITH_API */ std::cout << "Supported IO formats:" << std::endl; - plugin_dump(PLUGIN_TYPE_FORMAT); + plugin_dump(PluginType::FORMAT); std::cout << std::endl; printCopyright(); diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index eb12a146a..79b655947 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -75,8 +75,8 @@ public: enabled(en), limit(lim) { - pool.state = STATE_DESTROYED; - pool.queue.state = STATE_DESTROYED; + pool.state = State::DESTROYED; + pool.queue.state = State::DESTROYED; /* Initialize memory */ unsigned vec = LOG2_CEIL(MAX(node->out.vectorize, node->in.vectorize)); @@ -151,7 +151,7 @@ public: /* Fill in missing sequence numbers */ for (int i = 0; i < scanned; i++) { - if (smps[i]->flags & SAMPLE_HAS_SEQUENCE) + if (smps[i]->flags & (int) SampleFlags::HAS_SEQUENCE) last_sequenceno = smps[i]->sequence; else smps[i]->sequence = last_sequenceno++; @@ -211,7 +211,7 @@ public: recv = node_read(node, smps, allocated, &release); if (recv < 0) { - if (node->state == STATE_STOPPING || stop) + if (node->state == State::STOPPING || stop) goto leave2; else logger->warn("Failed to receive samples from node {}: reason={}", node_name(node), recv); @@ -255,7 +255,7 @@ public: if (ret) throw RuntimeError("Failed to initialize memory"); - io.state = STATE_DESTROYED; + io.state = State::DESTROYED; cfg_cli = json_object(); } @@ -416,7 +416,7 @@ check: if (optarg == endptr) if (!ft) throw RuntimeError("Invalid format: {}", format); - ret = io_init2(&io, ft, dtypes.c_str(), SAMPLE_HAS_ALL); + ret = io_init2(&io, ft, dtypes.c_str(), (int) SampleFlags::HAS_ALL); if (ret) throw RuntimeError("Failed to initialize IO"); diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index ad7a5a83b..0aa109dbc 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -59,12 +59,12 @@ public: { int ret; - n.state = STATE_DESTROYED; - n.in.state = STATE_DESTROYED; - n.out.state = STATE_DESTROYED; - io.state = STATE_DESTROYED; - q.state = STATE_DESTROYED; - q.queue.state = STATE_DESTROYED; + n.state = State::DESTROYED; + n.in.state = State::DESTROYED; + n.out.state = State::DESTROYED; + io.state = State::DESTROYED; + q.state = State::DESTROYED; + q.queue.state = State::DESTROYED; ret = memory_init(DEFAULT_NR_HUGEPAGES); if (ret) @@ -262,7 +262,7 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to start node {}: reason={}", node_name(&n), ret); - ret = io_init(&io, ft, &n.in.signals, IO_FLUSH | (SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET)); + ret = io_init(&io, ft, &n.in.signals, (int) IOFlags::FLUSH | ((int) SampleFlags::HAS_ALL & ~(int) SampleFlags::HAS_OFFSET)); if (ret) throw RuntimeError("Failed to initialize output"); @@ -282,7 +282,7 @@ check: if (optarg == endptr) if (ret) throw RuntimeError("Failed to start node {}: reason={}", node_name(&n), ret); - while (!stop && n.state == STATE_STARTED) { + while (!stop && n.state == State::STARTED) { t = sample_alloc(&q); unsigned release = 1; // release = allocated diff --git a/src/villas-test-cmp.cpp b/src/villas-test-cmp.cpp index fdd7544e7..2cab0962c 100644 --- a/src/villas-test-cmp.cpp +++ b/src/villas-test-cmp.cpp @@ -60,7 +60,7 @@ public: { int ret; - io.state = STATE_DESTROYED; + io.state = State::DESTROYED; ret = io_init2(&io, format, dtypes.c_str(), 0); if (ret) throw RuntimeError("Failed to initialize IO"); @@ -102,9 +102,9 @@ public: epsilon(1e-9), format("villas.human"), dtypes("64f"), - flags(SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA | SAMPLE_HAS_TS_ORIGIN) + flags((int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_TS_ORIGIN) { - pool.state = STATE_DESTROYED; + pool.state = State::DESTROYED; int ret; @@ -160,15 +160,15 @@ protected: goto check; case 'v': - flags &= ~SAMPLE_HAS_DATA; + flags &= ~(int) SampleFlags::HAS_DATA; break; case 'T': - flags &= ~SAMPLE_HAS_TS_ORIGIN; + flags &= ~(int) SampleFlags::HAS_TS_ORIGIN; break; case 's': - flags &= ~SAMPLE_HAS_SEQUENCE; + flags &= ~(int) SampleFlags::HAS_SEQUENCE; break; case 'f': diff --git a/tests/unit/io.cpp b/tests/unit/io.cpp index c50e7b077..4cf4ab85a 100644 --- a/tests/unit/io.cpp +++ b/tests/unit/io.cpp @@ -77,7 +77,7 @@ void fill_sample_data(struct vlist *signals, struct sample *smps[], unsigned cnt for (unsigned i = 0; i < cnt; i++) { struct sample *smp = smps[i]; - smps[i]->flags = SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA | SAMPLE_HAS_TS_ORIGIN; + smps[i]->flags = (int) SampleFlags::HAS_SEQUENCE | (int) SampleFlags::HAS_DATA | (int) SampleFlags::HAS_TS_ORIGIN; smps[i]->length = vlist_length(signals); smps[i]->sequence = 235 + i; smps[i]->ts.origin = now; @@ -88,22 +88,22 @@ void fill_sample_data(struct vlist *signals, struct sample *smps[], unsigned cnt union signal_data *data = &smp->data[j]; switch (sig->type) { - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: data->b = j * 0.1 + i * 100; break; - case SIGNAL_TYPE_COMPLEX: { + case SignalType::COMPLEX: { /** @todo: Port to proper C++ */ std::complex z = { j * 0.1f, i * 100.0f }; memcpy(&data->z, &z, sizeof(data->z)); break; } - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: data->f = j * 0.1 + i * 100; break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: data->i = j + i * 1000; break; @@ -119,32 +119,32 @@ void cr_assert_eq_sample(struct sample *a, struct sample *b, int flags) { cr_assert_eq(a->length, b->length); - if (flags & SAMPLE_HAS_SEQUENCE) + if (flags & (int) SampleFlags::HAS_SEQUENCE) cr_assert_eq(a->sequence, b->sequence); - if (flags & SAMPLE_HAS_TS_ORIGIN) { + if (flags & (int) SampleFlags::HAS_TS_ORIGIN) { cr_assert_eq(a->ts.origin.tv_sec, b->ts.origin.tv_sec); cr_assert_eq(a->ts.origin.tv_nsec, b->ts.origin.tv_nsec); } - if (flags & SAMPLE_HAS_DATA) { + if (flags & (int) SampleFlags::HAS_DATA) { for (unsigned j = 0; j < MIN(a->length, b->length); j++) { cr_assert_eq(sample_format(a, j), sample_format(b, j)); switch (sample_format(b, j)) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: cr_assert_float_eq(a->data[j].f, b->data[j].f, 1e-3, "Sample data mismatch at index %d: %f != %f", j, a->data[j].f, b->data[j].f); break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: cr_assert_eq(a->data[j].i, b->data[j].i, "Sample data mismatch at index %d: %lld != %lld", j, a->data[j].i, b->data[j].i); break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: cr_assert_eq(a->data[j].b, b->data[j].b, "Sample data mismatch at index %d: %s != %s", j, a->data[j].b ? "true" : "false", b->data[j].b ? "true" : "false"); break; - case SIGNAL_TYPE_COMPLEX: { + case SignalType::COMPLEX: { auto ca = * (std::complex *) &a->data[j].z; auto cb = * (std::complex *) &b->data[j].z; @@ -162,33 +162,33 @@ void cr_assert_eq_sample_raw(struct sample *a, struct sample *b, int flags, int { cr_assert_eq(a->length, b->length); - if (flags & SAMPLE_HAS_SEQUENCE) + if (flags & (int) SampleFlags::HAS_SEQUENCE) cr_assert_eq(a->sequence, b->sequence); - if (flags & SAMPLE_HAS_TS_ORIGIN) { + if (flags & (int) SampleFlags::HAS_TS_ORIGIN) { cr_assert_eq(a->ts.origin.tv_sec, b->ts.origin.tv_sec); cr_assert_eq(a->ts.origin.tv_nsec, b->ts.origin.tv_nsec); } - if (flags & SAMPLE_HAS_DATA) { + if (flags & (int) SampleFlags::HAS_DATA) { for (unsigned j = 0; j < MIN(a->length, b->length); j++) { cr_assert_eq(sample_format(a, j), sample_format(b, j)); switch (sample_format(b, j)) { - case SIGNAL_TYPE_FLOAT: + case SignalType::FLOAT: if (bits != 8 && bits != 16) cr_assert_float_eq(a->data[j].f, b->data[j].f, 1e-3, "Sample data mismatch at index %d: %f != %f", j, a->data[j].f, b->data[j].f); break; - case SIGNAL_TYPE_INTEGER: + case SignalType::INTEGER: cr_assert_eq(a->data[j].i, b->data[j].i, "Sample data mismatch at index %d: %lld != %lld", j, a->data[j].i, b->data[j].i); break; - case SIGNAL_TYPE_BOOLEAN: + case SignalType::BOOLEAN: cr_assert_eq(a->data[j].b, b->data[j].b, "Sample data mismatch at index %d: %s != %s", j, a->data[j].b ? "true" : "false", b->data[j].b ? "true" : "false"); break; - case SIGNAL_TYPE_COMPLEX: + case SignalType::COMPLEX: if (bits != 8 && bits != 16) { auto ca = * (std::complex *) &a->data[j].z; auto cb = * (std::complex *) &b->data[j].z; @@ -221,9 +221,9 @@ ParameterizedTest(struct param *p, io, lowlevel, .init = init_memory) struct format_type *f; - struct pool pool = { .state = STATE_DESTROYED }; - struct io io = { .state = STATE_DESTROYED }; - struct vlist signals = { .state = STATE_DESTROYED }; + struct pool pool = { .state = State::DESTROYED }; + struct io io = { .state = State::DESTROYED }; + struct vlist signals = { .state = State::DESTROYED }; struct sample *smps[p->cnt]; struct sample *smpt[p->cnt]; @@ -231,7 +231,7 @@ ParameterizedTest(struct param *p, io, lowlevel, .init = init_memory) cr_assert_eq(ret, 0); vlist_init(&signals); - signal_list_generate(&signals, NUM_VALUES, SIGNAL_TYPE_FLOAT); + signal_list_generate(&signals, NUM_VALUES, SignalType::FLOAT); ret = sample_alloc_many(&pool, smps, p->cnt); cr_assert_eq(ret, p->cnt); @@ -244,7 +244,7 @@ ParameterizedTest(struct param *p, io, lowlevel, .init = init_memory) f = format_type_lookup(p->fmt.c_str()); cr_assert_not_null(f, "Format '%s' does not exist", p->fmt.c_str()); - ret = io_init(&io, f, &signals, SAMPLE_HAS_ALL); + ret = io_init(&io, f, &signals, (int) SampleFlags::HAS_ALL); cr_assert_eq(ret, 0); ret = io_check(&io); @@ -290,9 +290,9 @@ ParameterizedTest(struct param *p, io, highlevel, .init = init_memory) struct format_type *f; - struct io io = { .state = STATE_DESTROYED }; - struct pool pool = { .state = STATE_DESTROYED }; - struct vlist signals = { .state = STATE_DESTROYED }; + struct io io = { .state = State::DESTROYED }; + struct pool pool = { .state = State::DESTROYED }; + struct vlist signals = { .state = State::DESTROYED }; struct sample *smps[p->cnt]; struct sample *smpt[p->cnt]; @@ -307,7 +307,7 @@ ParameterizedTest(struct param *p, io, highlevel, .init = init_memory) cr_assert_eq(ret, p->cnt); vlist_init(&signals); - signal_list_generate(&signals, NUM_VALUES, SIGNAL_TYPE_FLOAT); + signal_list_generate(&signals, NUM_VALUES, SignalType::FLOAT); fill_sample_data(&signals, smps, p->cnt); @@ -325,7 +325,7 @@ ParameterizedTest(struct param *p, io, highlevel, .init = init_memory) f = format_type_lookup(p->fmt.c_str()); cr_assert_not_null(f, "Format '%s' does not exist", p->fmt.c_str()); - ret = io_init(&io, f, &signals, SAMPLE_HAS_ALL); + ret = io_init(&io, f, &signals, (int) SampleFlags::HAS_ALL); cr_assert_eq(ret, 0); ret = io_check(&io); @@ -351,7 +351,7 @@ ParameterizedTest(struct param *p, io, highlevel, .init = init_memory) io_rewind(&io); - if (io.mode == IO_MODE_ADVIO) + if (io.mode == IOMode::ADVIO) adownload(io.in.stream.adv, 0); cnt = io_scan(&io, smpt, p->cnt); diff --git a/tests/unit/mapping.cpp b/tests/unit/mapping.cpp index ed6dd6c0d..c736d5363 100644 --- a/tests/unit/mapping.cpp +++ b/tests/unit/mapping.cpp @@ -34,7 +34,7 @@ Test(mapping, parse_nodes) { int ret; struct mapping_entry m; - struct vlist nodes = { .state = STATE_DESTROYED }; + struct vlist nodes = { .state = State::DESTROYED }; const char *node_names[3] = { "apple", "cherry", "carrot" }; const char *signal_names[3][4] = { @@ -49,14 +49,14 @@ Test(mapping, parse_nodes) struct node *n = new struct node; n->name = strdup(node_names[i]); - n->in.signals.state = STATE_DESTROYED; + n->in.signals.state = State::DESTROYED; vlist_init(&n->in.signals); for (unsigned j = 0; j < ARRAY_LEN(signal_names[i]); j++) { struct signal *sig; - sig = signal_create(signal_names[i][j], nullptr, SIGNAL_TYPE_FLOAT); + sig = signal_create(signal_names[i][j], nullptr, SignalType::FLOAT); cr_assert_not_null(sig); vlist_push(&n->in.signals, sig); @@ -68,41 +68,41 @@ Test(mapping, parse_nodes) ret = mapping_parse_str(&m, "apple.ts.origin", &nodes); cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "apple")); - cr_assert_eq(m.type, MAPPING_TYPE_TIMESTAMP); - cr_assert_eq(m.timestamp.type, MAPPING_TIMESTAMP_TYPE_ORIGIN); + cr_assert_eq(m.type, MappingType::TIMESTAMP); + cr_assert_eq(m.timestamp.type, MappingTimestampType::ORIGIN); ret = mapping_parse_str(&m, "cherry.stats.owd.mean", &nodes); cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "cherry")); - cr_assert_eq(m.type, MAPPING_TYPE_STATS); + cr_assert_eq(m.type, MappingType::STATS); cr_assert_eq(m.stats.metric, Stats::Metric::OWD); cr_assert_eq(m.stats.type, Stats::Type::MEAN); ret = mapping_parse_str(&m, "carrot.data[1-2]", &nodes); cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "carrot")); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 1); cr_assert_eq(m.length, 2); ret = mapping_parse_str(&m, "carrot", &nodes); cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "carrot")); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 0); cr_assert_eq(m.length, -1); ret = mapping_parse_str(&m, "carrot.data[sole]", &nodes); cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "carrot")); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 1); cr_assert_eq(m.length, 1); ret = mapping_parse_str(&m, "carrot.data[sole-mio]", &nodes); cr_assert_eq(ret, 0); cr_assert_eq(m.node, vlist_lookup(&nodes, "carrot")); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 1); cr_assert_eq(m.length, 2); @@ -117,47 +117,47 @@ Test(mapping, parse) ret = mapping_parse_str(&m, "ts.origin", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_TIMESTAMP); - cr_assert_eq(m.timestamp.type, MAPPING_TIMESTAMP_TYPE_ORIGIN); + cr_assert_eq(m.type, MappingType::TIMESTAMP); + cr_assert_eq(m.timestamp.type, MappingTimestampType::ORIGIN); ret = mapping_parse_str(&m, "hdr.sequence", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_HEADER); - cr_assert_eq(m.header.type, MAPPING_HEADER_TYPE_SEQUENCE); + cr_assert_eq(m.type, MappingType::HEADER); + cr_assert_eq(m.header.type, MappingHeaderType::SEQUENCE); ret = mapping_parse_str(&m, "stats.owd.mean", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_STATS); + cr_assert_eq(m.type, MappingType::STATS); cr_assert_eq(m.stats.metric, Stats::Metric::OWD); cr_assert_eq(m.stats.type, Stats::Type::MEAN); ret = mapping_parse_str(&m, "data[1-2]", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 1); cr_assert_eq(m.length, 2); ret = mapping_parse_str(&m, "data[5-5]", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 5); cr_assert_eq(m.length, 1); ret = mapping_parse_str(&m, "data[22]", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 22); cr_assert_eq(m.length, 1); ret = mapping_parse_str(&m, "data", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 0); cr_assert_eq(m.length, -1); ret = mapping_parse_str(&m, "data[]", nullptr); cr_assert_eq(ret, 0); - cr_assert_eq(m.type, MAPPING_TYPE_DATA); + cr_assert_eq(m.type, MappingType::DATA); cr_assert_eq(m.data.offset, 0); cr_assert_eq(m.length, -1); diff --git a/tests/unit/memory.cpp b/tests/unit/memory.cpp index 53cdb64a2..6034d6fd5 100644 --- a/tests/unit/memory.cpp +++ b/tests/unit/memory.cpp @@ -37,10 +37,10 @@ extern void init_memory(); TheoryDataPoints(memory, aligned) = { DataPoints(size_t, 1, 32, 55, 1 << 10, PAGESIZE, HUGEPAGESIZE), DataPoints(size_t, 1, 8, PAGESIZE, PAGESIZE), - DataPoints(enum memory_type_flags, MEMORY_HEAP, MEMORY_HUGEPAGE, MEMORY_HUGEPAGE) + DataPoints(enum MemoryFlags, MemoryFlags::HEAP, MemoryFlags::HUGEPAGE, MemoryFlags::HUGEPAGE) }; -Theory((size_t len, size_t align, enum memory_type_flags memory_type), memory, aligned, .init = init_memory) { +Theory((size_t len, size_t align, enum MemoryFlags memory_type), memory, aligned, .init = init_memory) { int ret; void *ptr; diff --git a/tests/unit/pool.cpp b/tests/unit/pool.cpp index 4962cb2e5..1edf50933 100644 --- a/tests/unit/pool.cpp +++ b/tests/unit/pool.cpp @@ -34,16 +34,16 @@ struct param { int thread_count; int pool_size; size_t block_size; - enum memory_type_flags memory_type; + enum MemoryFlags memory_type; }; ParameterizedTestParameters(pool, basic) { static struct param params[] = { - { 1, 4096, 150, MEMORY_HEAP }, - { 1, 128, 8, MEMORY_HUGEPAGE }, - { 1, 4, 8192, MEMORY_HUGEPAGE }, - { 1, 1 << 13, 4, MEMORY_HUGEPAGE } + { 1, 4096, 150, MemoryFlags::HEAP }, + { 1, 128, 8, MemoryFlags::HUGEPAGE }, + { 1, 4, 8192, MemoryFlags::HUGEPAGE }, + { 1, 1 << 13, 4, MemoryFlags::HUGEPAGE } }; return cr_make_param_array(struct param, params, ARRAY_LEN(params)); @@ -52,7 +52,7 @@ ParameterizedTestParameters(pool, basic) ParameterizedTest(struct param *p, pool, basic, .init = init_memory) { int ret; - struct pool pool = { .state = STATE_DESTROYED }; + struct pool pool = { .state = State::DESTROYED }; void *ptr, *ptrs[p->pool_size]; diff --git a/tests/unit/queue.cpp b/tests/unit/queue.cpp index 80feaefd2..d23cb6220 100644 --- a/tests/unit/queue.cpp +++ b/tests/unit/queue.cpp @@ -42,7 +42,7 @@ extern void init_memory(); #define SIZE (1 << 10) -static struct queue q = { .state = ATOMIC_VAR_INIT(STATE_DESTROYED) }; +static struct queue q = { .state = ATOMIC_VAR_INIT(State::DESTROYED) }; #if defined(_POSIX_BARRIERS) && _POSIX_BARRIERS > 0 static pthread_barrier_t barrier; @@ -54,7 +54,7 @@ struct param { int thread_count; bool many; int batch_size; - enum memory_type_flags memory_type; + enum MemoryFlags memory_type; volatile int start; struct queue queue; }; @@ -250,7 +250,7 @@ Test(queue, single_threaded, .init = init_memory) p.iter_count = 1 << 8; p.queue_size = 1 << 10; p.start = 1; /* we start immeadiatly */ - p.queue.state = ATOMIC_VAR_INIT(STATE_DESTROYED); + p.queue.state = ATOMIC_VAR_INIT(State::DESTROYED); ret = queue_init(&p.queue, p.queue_size, &memory_heap); cr_assert_eq(ret, 0, "Failed to create queue"); @@ -274,35 +274,35 @@ ParameterizedTestParameters(queue, multi_threaded) .thread_count = 32, .many = true, .batch_size = 10, - .memory_type = MEMORY_HEAP + .memory_type = MemoryFlags::HEAP }, { .iter_count = 1 << 8, .queue_size = 1 << 9, .thread_count = 4, .many = true, .batch_size = 100, - .memory_type = MEMORY_HEAP + .memory_type = MemoryFlags::HEAP }, { .iter_count = 1 << 16, .queue_size = 1 << 14, .thread_count = 16, .many = true, .batch_size = 100, - .memory_type = MEMORY_HEAP + .memory_type = MemoryFlags::HEAP }, { .iter_count = 1 << 8, .queue_size = 1 << 9, .thread_count = 4, .many = true, .batch_size = 10, - .memory_type = MEMORY_HEAP + .memory_type = MemoryFlags::HEAP }, { .iter_count = 1 << 16, .queue_size = 1 << 9, .thread_count = 16, .many = false, .batch_size = 10, - .memory_type = MEMORY_HUGEPAGE + .memory_type = MemoryFlags::HUGEPAGE } }; @@ -319,7 +319,7 @@ ParameterizedTest(struct param *p, queue, multi_threaded, .timeout = 20, .init = pthread_t threads[p->thread_count]; p->start = 0; - p->queue.state = ATOMIC_VAR_INIT(STATE_DESTROYED); + p->queue.state = ATOMIC_VAR_INIT(State::DESTROYED); struct memory_type *mt = memory_type_lookup(p->memory_type); @@ -368,7 +368,7 @@ Test(queue, init_destroy, .init = init_memory) int ret; struct queue q; - q.state = ATOMIC_VAR_INIT(STATE_DESTROYED); + q.state = ATOMIC_VAR_INIT(State::DESTROYED); ret = queue_init(&q, 1024, &memory_heap); cr_assert_eq(ret, 0); /* Should succeed */ diff --git a/tests/unit/queue_signalled.cpp b/tests/unit/queue_signalled.cpp index 77c8f0994..eae3a9af2 100644 --- a/tests/unit/queue_signalled.cpp +++ b/tests/unit/queue_signalled.cpp @@ -35,6 +35,7 @@ extern void init_memory(); #define NUM_ELEM 1000 struct param { + enum QueueSignalledMode mode; int flags; bool polled; }; @@ -112,14 +113,14 @@ again: ret = poll(&pfd, 1, -1); ParameterizedTestParameters(queue_signalled, simple) { static struct param params[] = { - { 0, false }, - { QUEUE_SIGNALLED_PTHREAD, false }, - { QUEUE_SIGNALLED_PTHREAD, false }, - { QUEUE_SIGNALLED_PTHREAD | QUEUE_SIGNALLED_PROCESS_SHARED, false }, - { QUEUE_SIGNALLED_POLLING, false }, + { QueueSignalledMode::AUTO, 0, false }, + { QueueSignalledMode::PTHREAD, 0, false }, + { QueueSignalledMode::PTHREAD, 0, false }, + { QueueSignalledMode::PTHREAD, (int) QueueSignalledFlags::PROCESS_SHARED, false }, + { QueueSignalledMode::POLLING, 0, false }, #if defined(__linux__) && defined(HAS_EVENTFD) - { QUEUE_SIGNALLED_EVENTFD, false }, - { QUEUE_SIGNALLED_EVENTFD, true } + { QueueSignalledMode::EVENTFD, 0, false }, + { QueueSignalledMode::EVENTFD, 0, true } #endif }; @@ -131,12 +132,12 @@ ParameterizedTest(struct param *param, queue_signalled, simple, .timeout = 5, .i int ret; void *r1, *r2; struct queue_signalled q; - q.queue.state = STATE_DESTROYED; + q.queue.state = State::DESTROYED; pthread_t t1, t2; - ret = queue_signalled_init(&q, LOG2_CEIL(NUM_ELEM), &memory_heap, param->flags); - cr_assert_eq(ret, 0, "Failed to initialize queue: flags=%#x, ret=%d", param->flags, ret); + ret = queue_signalled_init(&q, LOG2_CEIL(NUM_ELEM), &memory_heap, param->mode, param->flags); + cr_assert_eq(ret, 0, "Failed to initialize queue: mode=%d, flags=%#x, ret=%d", (int) param->mode, param->flags, ret); ret = pthread_create(&t1, nullptr, producer, &q); cr_assert_eq(ret, 0); From 150d4591fd184821158407773419db3e89f5bed8 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 16:57:00 +0200 Subject: [PATCH 26/94] replace C-style headers with C++ C-compatability headers --- common | 2 +- include/villas/api/session.hpp | 1 - include/villas/format_type.h | 2 +- include/villas/formats/csv.h | 2 +- include/villas/formats/msg_format.h | 2 +- include/villas/formats/protobuf.h | 2 +- include/villas/formats/raw.h | 2 +- include/villas/formats/villas_binary.h | 2 +- include/villas/formats/villas_human.h | 2 +- include/villas/kernel/tc.h | 2 +- include/villas/kernel/tc_netem.h | 2 +- include/villas/memory.h | 5 ++--- include/villas/memory_type.h | 4 ++-- include/villas/nodes/iec61850.hpp | 2 +- include/villas/nodes/iec61850_sv.hpp | 2 +- include/villas/nodes/zeromq.hpp | 2 +- include/villas/pool.h | 2 +- include/villas/queue.h | 4 ++-- include/villas/sample.h | 8 +++---- include/villas/signal.h | 25 ++++++++++++++++----- lib/config_helper.cpp | 2 +- lib/format_type.cpp | 4 ++-- lib/formats/csv.cpp | 6 ++--- lib/formats/json.cpp | 4 ++-- lib/formats/json_reserve.cpp | 2 +- lib/formats/protobuf.cpp | 6 ++--- lib/formats/raw.cpp | 31 ++++++++++++++------------ lib/formats/villas_binary.cpp | 2 +- lib/formats/villas_human.cpp | 5 ++--- lib/hook.cpp | 4 ++-- lib/hooks/average.cpp | 2 +- lib/hooks/cast.cpp | 2 +- lib/hooks/dp.cpp | 4 ++-- lib/hooks/drop.cpp | 2 +- lib/hooks/fix.cpp | 2 +- lib/hooks/jitter_calc.cpp | 4 ++-- lib/hooks/limit_rate.cpp | 2 +- lib/hooks/print.cpp | 2 +- lib/hooks/restart.cpp | 2 +- lib/hooks/scale.cpp | 6 ++--- lib/hooks/shift_ts.cpp | 2 +- lib/hooks/stats.cpp | 2 +- lib/io.cpp | 8 +++---- lib/kernel/if.cpp | 4 ++-- lib/kernel/nl.cpp | 2 +- lib/kernel/tc_netem.cpp | 2 +- lib/mapping.cpp | 2 +- lib/memory.cpp | 4 ++-- lib/memory/heap.cpp | 2 +- lib/memory/hugepage.cpp | 6 ++--- lib/memory/managed.cpp | 4 ++-- lib/node.cpp | 4 ++-- lib/node_type.cpp | 2 +- lib/nodes/amqp.cpp | 2 +- lib/nodes/comedi.cpp | 8 +++---- lib/nodes/file.cpp | 6 ++--- lib/nodes/iec61850.cpp | 2 +- lib/nodes/iec61850_sv.cpp | 2 +- lib/nodes/influxdb.cpp | 4 ++-- lib/nodes/loopback.cpp | 2 +- lib/nodes/mqtt.cpp | 2 +- lib/nodes/nanomsg.cpp | 2 +- lib/nodes/ngsi.cpp | 4 ++-- lib/nodes/opal.cpp | 4 ++-- lib/nodes/rtp.cpp | 6 ++--- lib/nodes/shmem.cpp | 2 +- lib/nodes/signal_generator.cpp | 4 ++-- lib/nodes/socket.cpp | 4 ++-- lib/nodes/stats.cpp | 2 +- lib/nodes/test_rtt.cpp | 4 ++-- lib/nodes/uldaq.cpp | 2 +- lib/nodes/websocket.cpp | 6 ++--- lib/nodes/zeromq.cpp | 2 +- lib/path.cpp | 10 ++++----- lib/plugin.cpp | 2 +- lib/sample.cpp | 10 ++++----- lib/shmem.cpp | 2 +- lib/signal.cpp | 18 +++++++-------- lib/socket_addr.cpp | 4 ++-- lib/stats.cpp | 2 +- lib/super_node.cpp | 4 ++-- lib/web.cpp | 2 +- src/villas-node.cpp | 2 +- src/villas-pipe.cpp | 5 ++--- src/villas-relay.cpp | 2 +- src/villas-signal.cpp | 4 ++-- src/villas-test-cmp.cpp | 1 - src/villas-test-rtt.cpp | 8 +++---- src/villas-zmq-keygen.cpp | 4 ++-- tests/unit/memory.cpp | 2 +- tests/unit/queue.cpp | 6 ++--- 91 files changed, 190 insertions(+), 181 deletions(-) diff --git a/common b/common index 86993dec0..c423c60f5 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 86993dec0a9aa7f83a7ade5f2cc79e2730b9c0df +Subproject commit c423c60f502a189bb636ce1c669e15438ee89299 diff --git a/include/villas/api/session.hpp b/include/villas/api/session.hpp index 9df5cd914..609d44c3e 100644 --- a/include/villas/api/session.hpp +++ b/include/villas/api/session.hpp @@ -23,7 +23,6 @@ #pragma once -#include #include #include diff --git a/include/villas/format_type.h b/include/villas/format_type.h index cc233effe..1947b7a0e 100644 --- a/include/villas/format_type.h +++ b/include/villas/format_type.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /* Forward declarations */ struct sample; diff --git a/include/villas/formats/csv.h b/include/villas/formats/csv.h index 97ca93a1f..51c137575 100644 --- a/include/villas/formats/csv.h +++ b/include/villas/formats/csv.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /* Forward declarations. */ struct io; diff --git a/include/villas/formats/msg_format.h b/include/villas/formats/msg_format.h index ed73c9953..b9da5952f 100644 --- a/include/villas/formats/msg_format.h +++ b/include/villas/formats/msg_format.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /** The current version number for the message format */ #define MSG_VERSION 2 diff --git a/include/villas/formats/protobuf.h b/include/villas/formats/protobuf.h index f02985536..fd8e514ab 100644 --- a/include/villas/formats/protobuf.h +++ b/include/villas/formats/protobuf.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /* Forward declarations */ struct sample; diff --git a/include/villas/formats/raw.h b/include/villas/formats/raw.h index 3b3742644..645f4a2d1 100644 --- a/include/villas/formats/raw.h +++ b/include/villas/formats/raw.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /* float128 is currently not yet supported as htole128() functions a missing */ #if 0 && defined(__GNUC__) && defined(__linux__) diff --git a/include/villas/formats/villas_binary.h b/include/villas/formats/villas_binary.h index 824e993fd..9f1e46264 100644 --- a/include/villas/formats/villas_binary.h +++ b/include/villas/formats/villas_binary.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /* Forward declarations. */ struct sample; diff --git a/include/villas/formats/villas_human.h b/include/villas/formats/villas_human.h index 51b03b382..ea8868ab5 100644 --- a/include/villas/formats/villas_human.h +++ b/include/villas/formats/villas_human.h @@ -23,7 +23,7 @@ #pragma once -#include +#include /* Forward declarations */ struct io; diff --git a/include/villas/kernel/tc.h b/include/villas/kernel/tc.h index 4fdcde5d2..13cb58a49 100644 --- a/include/villas/kernel/tc.h +++ b/include/villas/kernel/tc.h @@ -32,7 +32,7 @@ #pragma once -#include +#include #include #include diff --git a/include/villas/kernel/tc_netem.h b/include/villas/kernel/tc_netem.h index 868ced83b..36e553502 100644 --- a/include/villas/kernel/tc_netem.h +++ b/include/villas/kernel/tc_netem.h @@ -32,7 +32,7 @@ #pragma once -#include +#include #include #include diff --git a/include/villas/memory.h b/include/villas/memory.h index 55515c343..c69817ea5 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -23,9 +23,8 @@ #pragma once -#include -#include -#include +#include +#include #include #include diff --git a/include/villas/memory_type.h b/include/villas/memory_type.h index d8802d364..8e3a97e49 100644 --- a/include/villas/memory_type.h +++ b/include/villas/memory_type.h @@ -23,8 +23,8 @@ #pragma once -#include -#include +#include +#include /* Forward declarations */ struct memory_type; diff --git a/include/villas/nodes/iec61850.hpp b/include/villas/nodes/iec61850.hpp index d021411af..4059b08bf 100644 --- a/include/villas/nodes/iec61850.hpp +++ b/include/villas/nodes/iec61850.hpp @@ -29,7 +29,7 @@ #pragma once -#include +#include #ifdef __APPLE__ #include diff --git a/include/villas/nodes/iec61850_sv.hpp b/include/villas/nodes/iec61850_sv.hpp index fe47df111..3172893ef 100644 --- a/include/villas/nodes/iec61850_sv.hpp +++ b/include/villas/nodes/iec61850_sv.hpp @@ -29,7 +29,7 @@ #pragma once -#include +#include #include #include diff --git a/include/villas/nodes/zeromq.hpp b/include/villas/nodes/zeromq.hpp index b1f2fe31d..5e88b4445 100644 --- a/include/villas/nodes/zeromq.hpp +++ b/include/villas/nodes/zeromq.hpp @@ -29,7 +29,7 @@ #pragma once -#include +#include #include #include diff --git a/include/villas/pool.h b/include/villas/pool.h index 027787c2e..df07aa037 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -25,7 +25,7 @@ #pragma once -#include +#include #include #include diff --git a/include/villas/queue.h b/include/villas/queue.h index 5836b2282..dbb87af4a 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -35,8 +35,8 @@ #include -#include -#include +#include +#include #include #include diff --git a/include/villas/sample.h b/include/villas/sample.h index bc2aa0480..5923b90d6 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -25,10 +25,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include diff --git a/include/villas/signal.h b/include/villas/signal.h index f73f22831..33989f5ba 100644 --- a/include/villas/signal.h +++ b/include/villas/signal.h @@ -23,12 +23,13 @@ #pragma once -#include - #include -#include -#include -#include + +#include +#include +#include + +#include /* "I" defined by complex.h collides with a define in OpenSSL */ #undef I @@ -46,7 +47,19 @@ union signal_data { double f; /**< Floating point values. */ int64_t i; /**< Integer values. */ bool b; /**< Boolean values. */ - float _Complex z; /**< Complex values. */ + std::complex z; /**< Complex values. */ + + signal_data() + { } + + static union signal_data nan() + { + union signal_data d; + + d.f = std::numeric_limits::quiet_NaN(); + + return d; + } }; enum class SignalType { diff --git a/lib/config_helper.cpp b/lib/config_helper.cpp index 4dd86ba51..ee93e989a 100644 --- a/lib/config_helper.cpp +++ b/lib/config_helper.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/lib/format_type.cpp b/lib/format_type.cpp index bf5b84c06..a76ce8dae 100644 --- a/lib/format_type.cpp +++ b/lib/format_type.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/formats/csv.cpp b/lib/formats/csv.cpp index 26ae90be2..64ef38634 100644 --- a/lib/formats/csv.cpp +++ b/lib/formats/csv.cpp @@ -20,9 +20,9 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include -#include +#include +#include +#include #include #include diff --git a/lib/formats/json.cpp b/lib/formats/json.cpp index d2a33e326..a0b53850b 100644 --- a/lib/formats/json.cpp +++ b/lib/formats/json.cpp @@ -141,8 +141,8 @@ static int json_pack_sample(struct io *io, json_t **j, struct sample *smp) case SignalType::COMPLEX: json_value = json_pack("{ s: f, s: f }", - "real", creal(smp->data[i].z), - "imag", cimag(smp->data[i].z) + "real", std::real(smp->data[i].z), + "imag", std::imag(smp->data[i].z) ); break; diff --git a/lib/formats/json_reserve.cpp b/lib/formats/json_reserve.cpp index 18e1849a9..2a51ec8df 100644 --- a/lib/formats/json_reserve.cpp +++ b/lib/formats/json_reserve.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/formats/protobuf.cpp b/lib/formats/protobuf.cpp index 2a4a02342..eb83fc99a 100644 --- a/lib/formats/protobuf.cpp +++ b/lib/formats/protobuf.cpp @@ -113,8 +113,8 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct villas__node__complex__init(pb_val->z); - pb_val->z->real = creal(smp->data[j].z); - pb_val->z->imag = cimag(smp->data[j].z); + pb_val->z->real = std::real(smp->data[j].z); + pb_val->z->imag = std::imag(smp->data[j].z); break; case SignalType::INVALID: @@ -202,7 +202,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s break; case SignalType::COMPLEX: - smp->data[j].z = pb_val->z->real + _Complex_I * pb_val->z->imag; + smp->data[j].z = std::complex(pb_val->z->real, pb_val->z->imag); break; default: { } diff --git a/lib/formats/raw.cpp b/lib/formats/raw.cpp index 09da1c4bd..ea70126a8 100644 --- a/lib/formats/raw.cpp +++ b/lib/formats/raw.cpp @@ -216,18 +216,18 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp break; case 32: - f32[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 32, (float) creal(data->z)); - f32[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 32, (float ) cimag(data->z)); + f32[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 32, (float) std::real(data->z)); + f32[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 32, (float) std::imag(data->z)); break; case 64: - f64[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 64, creal(data->z)); - f64[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 64, cimag(data->z)); + f64[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 64, std::real(data->z)); + f64[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 64, std::imag(data->z)); break; #ifdef HAS_128BIT case 128: - f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, creal(data->z); - f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, cimag(data->z); + f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, std::real(data->z); + f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, std::imag(data->z); break; #endif } @@ -369,21 +369,24 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct case SignalType::COMPLEX: switch (bits) { - case 8: data->z = -1 + _Complex_I * -1; o += 2; break; /* Not supported */ - case 16: data->z = -1 + _Complex_I * -1; o += 2; break; /* Not supported */ + case 8: data->z = std::complex(-1, -1); o += 2; break; /* Not supported */ + case 16: data->z = std::complex(-1, -1); o += 2; break; /* Not supported */ - case 32: data->z = SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++]) - + _Complex_I * SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++]); + case 32: data->z = std::complex( + SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++]), + SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++])); break; - case 64: data->z = SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++]) - + _Complex_I * SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++]); + case 64: data->z = std::complex( + SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++]), + SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++])); break; #if HAS_128BIT - case 128: data->z = SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++]) - + _Complex_I * SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++]); + case 128: data->z = std::complex( + SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++]), + SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++])); break; #endif } diff --git a/lib/formats/villas_binary.cpp b/lib/formats/villas_binary.cpp index b9526514d..7c0f58e41 100644 --- a/lib/formats/villas_binary.cpp +++ b/lib/formats/villas_binary.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/formats/villas_human.cpp b/lib/formats/villas_human.cpp index 538ae5d25..f34880a99 100644 --- a/lib/formats/villas_human.cpp +++ b/lib/formats/villas_human.cpp @@ -20,9 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include -#include +#include +#include #include #include diff --git a/lib/hook.cpp b/lib/hook.cpp index 1c2249557..0f9c9c1f3 100644 --- a/lib/hook.cpp +++ b/lib/hook.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/hooks/average.cpp b/lib/hooks/average.cpp index 203b92206..d2135f491 100644 --- a/lib/hooks/average.cpp +++ b/lib/hooks/average.cpp @@ -26,7 +26,7 @@ #include -#include +#include #include #include diff --git a/lib/hooks/cast.cpp b/lib/hooks/cast.cpp index fed533b9e..fc2c9762a 100644 --- a/lib/hooks/cast.cpp +++ b/lib/hooks/cast.cpp @@ -25,7 +25,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/dp.cpp b/lib/hooks/dp.cpp index c650c57f6..f26e24b9e 100644 --- a/lib/hooks/dp.cpp +++ b/lib/hooks/dp.cpp @@ -24,8 +24,8 @@ * @{ */ -#include -#include +#include +#include #include diff --git a/lib/hooks/drop.cpp b/lib/hooks/drop.cpp index e80894828..98fbb3c04 100644 --- a/lib/hooks/drop.cpp +++ b/lib/hooks/drop.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/fix.cpp b/lib/hooks/fix.cpp index 5b1239ebb..44b2b95c0 100644 --- a/lib/hooks/fix.cpp +++ b/lib/hooks/fix.cpp @@ -25,7 +25,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/jitter_calc.cpp b/lib/hooks/jitter_calc.cpp index a247815fa..89fa43e96 100644 --- a/lib/hooks/jitter_calc.cpp +++ b/lib/hooks/jitter_calc.cpp @@ -24,8 +24,8 @@ * @{ */ -#include -#include +#include +#include #include #include diff --git a/lib/hooks/limit_rate.cpp b/lib/hooks/limit_rate.cpp index 887bfc68b..f806f2e05 100644 --- a/lib/hooks/limit_rate.cpp +++ b/lib/hooks/limit_rate.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/print.cpp b/lib/hooks/print.cpp index 5b955d093..1b3841dba 100644 --- a/lib/hooks/print.cpp +++ b/lib/hooks/print.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/restart.cpp b/lib/hooks/restart.cpp index 838850723..902446e5b 100644 --- a/lib/hooks/restart.cpp +++ b/lib/hooks/restart.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/scale.cpp b/lib/hooks/scale.cpp index b470ff190..ef0af7b72 100644 --- a/lib/hooks/scale.cpp +++ b/lib/hooks/scale.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include @@ -116,11 +116,11 @@ public: break; case SignalType::COMPLEX: - smp->data[k].z = smp->data[k].z * scale + offset; + smp->data[k].z = smp->data[k].z * (float) scale + (float) offset; break; case SignalType::BOOLEAN: - smp->data[k].b = smp->data[k].b * scale + offset; + smp->data[k].b = smp->data[k].b * (float) scale + (float) offset; break; default: { } diff --git a/lib/hooks/shift_ts.cpp b/lib/hooks/shift_ts.cpp index 96c014e06..48e533efd 100644 --- a/lib/hooks/shift_ts.cpp +++ b/lib/hooks/shift_ts.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp index 9439dd1ab..32ff01be5 100644 --- a/lib/hooks/stats.cpp +++ b/lib/hooks/stats.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include diff --git a/lib/io.cpp b/lib/io.cpp index c20dacc68..98412657e 100644 --- a/lib/io.cpp +++ b/lib/io.cpp @@ -20,11 +20,11 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include -#include +#include +#include +#include #include -#include +#include #include #include diff --git a/lib/kernel/if.cpp b/lib/kernel/if.cpp index 01154721a..9ec234745 100644 --- a/lib/kernel/if.cpp +++ b/lib/kernel/if.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/kernel/nl.cpp b/lib/kernel/nl.cpp index 721c2c07a..5646a139f 100644 --- a/lib/kernel/nl.cpp +++ b/lib/kernel/nl.cpp @@ -22,7 +22,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/kernel/tc_netem.cpp b/lib/kernel/tc_netem.cpp index 3df26e03e..052ec3ffd 100644 --- a/lib/kernel/tc_netem.cpp +++ b/lib/kernel/tc_netem.cpp @@ -23,7 +23,7 @@ *********************************************************************************/ #include -#include +#include #include diff --git a/lib/mapping.cpp b/lib/mapping.cpp index fc2e167a9..3616bb918 100644 --- a/lib/mapping.cpp +++ b/lib/mapping.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/memory.cpp b/lib/memory.cpp index a5a3eb0fe..4bba823d6 100644 --- a/lib/memory.cpp +++ b/lib/memory.cpp @@ -22,9 +22,9 @@ #include -#include +#include #include -#include +#include #include #include diff --git a/lib/memory/heap.cpp b/lib/memory/heap.cpp index e718aea6c..c376a8cde 100644 --- a/lib/memory/heap.cpp +++ b/lib/memory/heap.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/memory/hugepage.cpp b/lib/memory/hugepage.cpp index b460e266c..091e9383b 100644 --- a/lib/memory/hugepage.cpp +++ b/lib/memory/hugepage.cpp @@ -20,11 +20,9 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include -#include -#include #include #include diff --git a/lib/memory/managed.cpp b/lib/memory/managed.cpp index c2631929f..def48ca27 100644 --- a/lib/memory/managed.cpp +++ b/lib/memory/managed.cpp @@ -20,9 +20,9 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include -#include +#include #include #include diff --git a/lib/node.cpp b/lib/node.cpp index edb4ac922..9250f2cd5 100644 --- a/lib/node.cpp +++ b/lib/node.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/node_type.cpp b/lib/node_type.cpp index d8c20a00d..3ab35e5ba 100644 --- a/lib/node_type.cpp +++ b/lib/node_type.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/nodes/amqp.cpp b/lib/nodes/amqp.cpp index a99776266..7652b5483 100644 --- a/lib/nodes/amqp.cpp +++ b/lib/nodes/amqp.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/nodes/comedi.cpp b/lib/nodes/comedi.cpp index b6ecf293d..ce6a42c52 100644 --- a/lib/nodes/comedi.cpp +++ b/lib/nodes/comedi.cpp @@ -21,8 +21,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include #include @@ -598,7 +598,7 @@ int comedi_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r smps[i]->data[si].f = comedi_to_phys(raw, d->chanspecs[si].range, d->chanspecs[si].maxdata); - if (isnan(smps[i]->data[si].f)) + if (std::isnan(smps[i]->data[si].f)) warning("Input: channel %d clipped", CR_CHAN(d->chanlist[si])); } } @@ -895,7 +895,7 @@ int comedi_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned * case SignalType::COMPLEX: /* We only output the real part */ - raw_value = comedi_from_phys(creal(sample->data[si].z), d->chanspecs[si].range, d->chanspecs[si].maxdata); + raw_value = comedi_from_phys(std::real(sample->data[si].z), d->chanspecs[si].range, d->chanspecs[si].maxdata); break; case SignalType::INVALID: diff --git a/lib/nodes/file.cpp b/lib/nodes/file.cpp index 8d2961f10..28c5415f9 100644 --- a/lib/nodes/file.cpp +++ b/lib/nodes/file.cpp @@ -21,11 +21,11 @@ *********************************************************************************/ #include -#include -#include +#include +#include #include #include -#include +#include #include #include diff --git a/lib/nodes/iec61850.cpp b/lib/nodes/iec61850.cpp index 7b0c8a1ad..6f8935bf1 100644 --- a/lib/nodes/iec61850.cpp +++ b/lib/nodes/iec61850.cpp @@ -22,7 +22,7 @@ #include -#include +#include #include #include diff --git a/lib/nodes/iec61850_sv.cpp b/lib/nodes/iec61850_sv.cpp index e791ab9cd..9bada0d21 100644 --- a/lib/nodes/iec61850_sv.cpp +++ b/lib/nodes/iec61850_sv.cpp @@ -24,7 +24,7 @@ #if CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1 -#include +#include #include #include diff --git a/lib/nodes/influxdb.cpp b/lib/nodes/influxdb.cpp index f872e0e33..53d4915a5 100644 --- a/lib/nodes/influxdb.cpp +++ b/lib/nodes/influxdb.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include #include diff --git a/lib/nodes/loopback.cpp b/lib/nodes/loopback.cpp index 23d654713..68e0e21b5 100644 --- a/lib/nodes/loopback.cpp +++ b/lib/nodes/loopback.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index fdfbb638c..9cee077d8 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/nodes/nanomsg.cpp b/lib/nodes/nanomsg.cpp index 5382bd4ad..52233b911 100644 --- a/lib/nodes/nanomsg.cpp +++ b/lib/nodes/nanomsg.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/lib/nodes/ngsi.cpp b/lib/nodes/ngsi.cpp index 4c8a8a6a4..949fdc4f2 100644 --- a/lib/nodes/ngsi.cpp +++ b/lib/nodes/ngsi.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . **********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/nodes/opal.cpp b/lib/nodes/opal.cpp index 12864299d..d1bb69aa0 100644 --- a/lib/nodes/opal.cpp +++ b/lib/nodes/opal.cpp @@ -22,8 +22,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/nodes/rtp.cpp b/lib/nodes/rtp.cpp index 33adfdde1..ff0941096 100644 --- a/lib/nodes/rtp.cpp +++ b/lib/nodes/rtp.cpp @@ -21,10 +21,10 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include -#include -#include +#include +#include #include #include diff --git a/lib/nodes/shmem.cpp b/lib/nodes/shmem.cpp index 37d61769e..94422147b 100644 --- a/lib/nodes/shmem.cpp +++ b/lib/nodes/shmem.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/nodes/signal_generator.cpp b/lib/nodes/signal_generator.cpp index 76f9ac9ab..f3832c14d 100644 --- a/lib/nodes/signal_generator.cpp +++ b/lib/nodes/signal_generator.cpp @@ -21,8 +21,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/nodes/socket.cpp b/lib/nodes/socket.cpp index 15a7b1df6..c7e9202d8 100644 --- a/lib/nodes/socket.cpp +++ b/lib/nodes/socket.cpp @@ -21,8 +21,8 @@ *********************************************************************************/ #include -#include -#include +#include +#include #include #include diff --git a/lib/nodes/stats.cpp b/lib/nodes/stats.cpp index 73df9369e..d2c2a9dca 100644 --- a/lib/nodes/stats.cpp +++ b/lib/nodes/stats.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/nodes/test_rtt.cpp b/lib/nodes/test_rtt.cpp index 46a6dc82c..d9517f8b3 100644 --- a/lib/nodes/test_rtt.cpp +++ b/lib/nodes/test_rtt.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/nodes/uldaq.cpp b/lib/nodes/uldaq.cpp index 42f40469f..4e7186c76 100644 --- a/lib/nodes/uldaq.cpp +++ b/lib/nodes/uldaq.cpp @@ -22,7 +22,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/nodes/websocket.cpp b/lib/nodes/websocket.cpp index cf5a40ad2..6228144db 100644 --- a/lib/nodes/websocket.cpp +++ b/lib/nodes/websocket.cpp @@ -20,10 +20,10 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include -#include +#include #include #include diff --git a/lib/nodes/zeromq.cpp b/lib/nodes/zeromq.cpp index 48eb0f471..4f3fdd55e 100644 --- a/lib/nodes/zeromq.cpp +++ b/lib/nodes/zeromq.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #if ZMQ_VERSION_MAJOR < 4 || (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR <= 1) diff --git a/lib/path.cpp b/lib/path.cpp index ed811799a..245082bac 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -20,13 +20,13 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include +#include +#include + #include -#include -#include #include -#include #include #include diff --git a/lib/plugin.cpp b/lib/plugin.cpp index 1e1731b03..752095878 100644 --- a/lib/plugin.cpp +++ b/lib/plugin.cpp @@ -21,7 +21,7 @@ *********************************************************************************/ #include -#include +#include #include diff --git a/lib/sample.cpp b/lib/sample.cpp index ecbf83325..631ac2b13 100644 --- a/lib/sample.cpp +++ b/lib/sample.cpp @@ -20,9 +20,9 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include -#include +#include +#include +#include #include #include @@ -265,8 +265,8 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags) break; case SignalType::COMPLEX: - if (cabs(a->data[i].z - b->data[i].z) > epsilon) { - printf("data[%d].z: %f+%fi != %f+%fi\n", i, creal(a->data[i].z), cimag(a->data[i].z), creal(b->data[i].z), cimag(b->data[i].z)); + if (std::abs(a->data[i].z - b->data[i].z) > epsilon) { + printf("data[%d].z: %f+%fi != %f+%fi\n", i, std::real(a->data[i].z), std::imag(a->data[i].z), std::real(b->data[i].z), std::imag(b->data[i].z)); return 5; } break; diff --git a/lib/shmem.cpp b/lib/shmem.cpp index 6883f1599..cba1e4d90 100644 --- a/lib/shmem.cpp +++ b/lib/shmem.cpp @@ -21,7 +21,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include #include diff --git a/lib/signal.cpp b/lib/signal.cpp index dcdd4a54f..0478d114a 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include #include @@ -466,7 +466,7 @@ void signal_data_set(union signal_data *data, const struct signal *sig, double v break; case SignalType::INVALID: - memset(data, 0, sizeof(union signal_data)); + *data = signal_data::nan(); break; } } @@ -492,7 +492,7 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const break; case SignalType::COMPLEX: - data->b = creal(data->z); + data->b = std::real(data->z); break; default: { } @@ -514,7 +514,7 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const break; case SignalType::COMPLEX: - data->i = creal(data->z); + data->i = std::real(data->z); break; default: { } @@ -536,7 +536,7 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const break; case SignalType::COMPLEX: - data->f = creal(data->z); + data->f = std::real(data->z); break; default: { } @@ -602,7 +602,7 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con (*end)++; - data->z = real + _Complex_I * imag; + data->z = std::complex(real, imag); break; } @@ -641,7 +641,7 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js if (ret) return -2; - data->z = real + _Complex_I * imag; + data->z = std::complex(real, imag); break; } @@ -665,7 +665,7 @@ int signal_data_snprint(const union signal_data *data, const struct signal *sig, return snprintf(buf, len, "%u", data->b); case SignalType::COMPLEX: - return snprintf(buf, len, "%.6f%+.6fi", creal(data->z), cimag(data->z)); + return snprintf(buf, len, "%.6f%+.6fi", std::real(data->z), std::imag(data->z)); default: return 0; diff --git a/lib/socket_addr.cpp b/lib/socket_addr.cpp index d4bfbc09d..f8fbe78a5 100644 --- a/lib/socket_addr.cpp +++ b/lib/socket_addr.cpp @@ -21,8 +21,8 @@ */ #include -#include -#include +#include +#include #include #include diff --git a/lib/stats.cpp b/lib/stats.cpp index a00220783..b698a10ab 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/lib/super_node.cpp b/lib/super_node.cpp index 9d4731385..bbeb0ec1c 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -20,8 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include diff --git a/lib/web.cpp b/lib/web.cpp index 950d609bd..de2db734f 100644 --- a/lib/web.cpp +++ b/lib/web.cpp @@ -21,7 +21,7 @@ *********************************************************************************/ #include -#include +#include #include #include diff --git a/src/villas-node.cpp b/src/villas-node.cpp index 295f42c68..165f0fc28 100644 --- a/src/villas-node.cpp +++ b/src/villas-node.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . *********************************************************************************/ -#include +#include #include #include diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index 79b655947..f2d1c0dea 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -24,10 +24,9 @@ * @{ *********************************************************************************/ -#include -#include +#include +#include #include -#include #include #include diff --git a/src/villas-relay.cpp b/src/villas-relay.cpp index b817837e7..fe8264bbb 100644 --- a/src/villas-relay.cpp +++ b/src/villas-relay.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 0aa109dbc..446ba5e16 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -25,8 +25,8 @@ **********************************************************************************/ #include -#include -#include +#include +#include #include #include diff --git a/src/villas-test-cmp.cpp b/src/villas-test-cmp.cpp index 2cab0962c..080f43fae 100644 --- a/src/villas-test-cmp.cpp +++ b/src/villas-test-cmp.cpp @@ -21,7 +21,6 @@ *********************************************************************************/ #include -#include #include #include diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index 391f56dbf..42898f805 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -20,13 +20,13 @@ * along with this program. If not, see . *********************************************************************************/ -#include -#include +#include +#include #include #include -#include +#include #include -#include +#include #include #include diff --git a/src/villas-zmq-keygen.cpp b/src/villas-zmq-keygen.cpp index 4dbd0a566..7f7cda8a1 100644 --- a/src/villas-zmq-keygen.cpp +++ b/src/villas-zmq-keygen.cpp @@ -28,8 +28,8 @@ *********************************************************************************/ #include -#include -#include +#include +#include #include #include diff --git a/tests/unit/memory.cpp b/tests/unit/memory.cpp index 6034d6fd5..ca03dc409 100644 --- a/tests/unit/memory.cpp +++ b/tests/unit/memory.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/tests/unit/queue.cpp b/tests/unit/queue.cpp index d23cb6220..714e8b357 100644 --- a/tests/unit/queue.cpp +++ b/tests/unit/queue.cpp @@ -22,9 +22,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include From ef1c3394333f147bf21cb39cd2aaa4fdce5b24c9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 16:58:28 +0200 Subject: [PATCH 27/94] replace NULL by nullptr --- common | 2 +- include/villas/io.h | 2 +- include/villas/memory.h | 2 +- include/villas/pool.h | 2 +- include/villas/sample.h | 2 +- lib/formats/json.cpp | 6 +++--- lib/formats/json_reserve.cpp | 14 +++++++------- lib/formats/protobuf.cpp | 8 ++++---- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/common b/common index c423c60f5..39e23fc9a 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c423c60f502a189bb636ce1c669e15438ee89299 +Subproject commit 39e23fc9a7234e7a235efd49e6cdc21ae370ed93 diff --git a/include/villas/io.h b/include/villas/io.h index 42bf0f81c..0a1f71aa0 100644 --- a/include/villas/io.h +++ b/include/villas/io.h @@ -138,7 +138,7 @@ int io_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct * * @param buf[out] The buffer which should be filled with serialized data. * @param len[in] The length of the buffer \p buf. - * @param rbytes[out] The number of bytes which have been written to \p buf. Ignored if NULL. + * @param rbytes[out] The number of bytes which have been written to \p buf. Ignored if nullptr. * @param smps[in] The array of pointers to samples. * @param cnt[in] The number of pointers in the array \p smps. * diff --git a/include/villas/memory.h b/include/villas/memory.h index c69817ea5..a7d370dac 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -70,7 +70,7 @@ int memory_lock(size_t lock); /** Allocate \p len bytes memory of type \p m. * - * @retval NULL If allocation failed. + * @retval nullptr If allocation failed. * @retval <>0 If allocation was successful. */ void * memory_alloc(struct memory_type *m, size_t len); diff --git a/include/villas/pool.h b/include/villas/pool.h index df07aa037..259950080 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -83,7 +83,7 @@ INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt) INLINE void * pool_get(struct pool *p) { void *ptr; - return queue_pull(&p->queue, &ptr) == 1 ? ptr : NULL; + return queue_pull(&p->queue, &ptr) == 1 ? ptr : nullptr; } /** Release a memory block back to the pool. */ diff --git a/include/villas/sample.h b/include/villas/sample.h index 5923b90d6..cde004c57 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -93,7 +93,7 @@ struct sample { #define SAMPLE_NON_POOL PTRDIFF_MIN /** Get the address of the pool to which the sample belongs. */ -#define sample_pool(s) ((s)->pool_off == SAMPLE_NON_POOL ? NULL : (struct pool *) ((char *) (s) + (s)->pool_off)) +#define sample_pool(s) ((s)->pool_off == SAMPLE_NON_POOL ? nullptr : (struct pool *) ((char *) (s) + (s)->pool_off)) struct sample * sample_alloc(struct pool *p); diff --git a/lib/formats/json.cpp b/lib/formats/json.cpp index a0b53850b..1b75a0293 100644 --- a/lib/formats/json.cpp +++ b/lib/formats/json.cpp @@ -77,8 +77,8 @@ static int json_unpack_timestamps(json_t *json_ts, struct sample *smp) { int ret; json_error_t err; - json_t *json_ts_origin = NULL; - json_t *json_ts_received = NULL; + json_t *json_ts_origin = nullptr; + json_t *json_ts_received = nullptr; json_unpack_ex(json_ts, &err, 0, "{ s?: o, s?: o }", "origin", &json_ts_origin, @@ -185,7 +185,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm { int ret; json_error_t err; - json_t *json_data, *json_value, *json_ts = NULL; + json_t *json_data, *json_value, *json_ts = nullptr; size_t i; int64_t sequence = -1; diff --git a/lib/formats/json_reserve.cpp b/lib/formats/json_reserve.cpp index 2a51ec8df..1a98b8112 100644 --- a/lib/formats/json_reserve.cpp +++ b/lib/formats/json_reserve.cpp @@ -37,8 +37,8 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm { json_error_t err; json_t *json_data, *json_name, *json_unit, *json_value; - json_t *json_created = NULL; - json_t *json_sequence = NULL; + json_t *json_created = nullptr; + json_t *json_sequence = nullptr; if (smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) json_created = json_integer(time_to_double(&smp->ts.origin) * 1e3); @@ -67,7 +67,7 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm if (sig->unit) json_unit = json_string(sig->unit); else - json_unit = NULL; + json_unit = nullptr; json_value = json_pack_ex(&err, 0, "{ s: o, s: f }", "name", json_name, @@ -94,7 +94,7 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm *j = json_pack_ex(&err, 0, "{ s: o }", "measurements", json_data ); - if (*j == NULL) + if (*j == nullptr) return -1; #if 0 #ifdef JSON_RESERVE_INTEGER_TARGET @@ -124,8 +124,8 @@ static int json_reserve_unpack_sample(struct io *io, json_t *json_smp, struct sa int ret, idx; double created = -1; json_error_t err; - json_t *json_value, *json_data = NULL; - json_t *json_origin = NULL, *json_target = NULL; + json_t *json_value, *json_data = nullptr; + json_t *json_origin = nullptr, *json_target = nullptr; size_t i; ret = json_unpack_ex(json_smp, &err, 0, "{ s?: o, s?: o, s?: o, s?: o }", @@ -173,7 +173,7 @@ static int json_reserve_unpack_sample(struct io *io, json_t *json_smp, struct sa smp->length = 0; json_array_foreach(json_data, i, json_value) { - const char *name, *unit = NULL; + const char *name, *unit = nullptr; double value; ret = json_unpack_ex(json_value, &err, 0, "{ s: s, s?: s, s: F, s?: F }", diff --git a/lib/formats/protobuf.cpp b/lib/formats/protobuf.cpp index eb83fc99a..2b764cd09 100644 --- a/lib/formats/protobuf.cpp +++ b/lib/formats/protobuf.cpp @@ -130,14 +130,14 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct goto out; villas__node__message__pack(pb_msg, (uint8_t *) buf); - villas__node__message__free_unpacked(pb_msg, NULL); + villas__node__message__free_unpacked(pb_msg, nullptr); *wbytes = psz; return cnt; out: - villas__node__message__free_unpacked(pb_msg, NULL); + villas__node__message__free_unpacked(pb_msg, nullptr); return -1; } @@ -147,7 +147,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s unsigned i, j; Villas__Node__Message *pb_msg; - pb_msg = villas__node__message__unpack(NULL, len, (uint8_t *) buf); + pb_msg = villas__node__message__unpack(nullptr, len, (uint8_t *) buf); if (!pb_msg) return -1; @@ -218,7 +218,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s if (rbytes) *rbytes = villas__node__message__get_packed_size(pb_msg); - villas__node__message__free_unpacked(pb_msg, NULL); + villas__node__message__free_unpacked(pb_msg, nullptr); return i; } From abd8a7d92b7480945dcbaab3e9c023cad2dc4e5c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 17:22:03 +0200 Subject: [PATCH 28/94] exec: show more details --- lib/nodes/exec.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index 6400e2d81..39a757b85 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -214,10 +214,14 @@ char * exec_print(struct node *n) struct exec *e = (struct exec *) n->_vd; char *buf = nullptr; - strcatf(&buf, "format=%s, exec=%s, flush=%s", + strcatf(&buf, "format=%s, exec=%s, shell=%s, flush=%s, #environment=%zu, #arguments=%zu, working_dir=%s", format_type_name(e->format), e->command.c_str(), - e->flush ? "yes" : "no" + e->shell ? "yes" : "no", + e->flush ? "yes" : "no", + e->environment.size(), + e->arguments.size(), + e->working_dir.c_str() ); return buf; From d4fbf83054b130a4c5aaed2bd6d2686f8826a241 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 17:35:05 +0200 Subject: [PATCH 29/94] exec: enable flushing by default --- lib/nodes/exec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index 39a757b85..7315df640 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -36,7 +36,7 @@ int exec_parse(struct node *n, json_t *cfg) struct exec *e = (struct exec *) n->_vd; json_error_t err; - int ret, flush = 0; + int ret, flush = 1; json_t *json_exec; json_t *json_env = nullptr; From 39f28149afa6153688f738d47873337d1737b261 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 23 Jun 2019 17:35:28 +0200 Subject: [PATCH 30/94] exec: fix argument parsing --- lib/nodes/exec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index 7315df640..f9f890a1a 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -83,8 +83,8 @@ int exec_parse(struct node *n, json_t *cfg) if (i == 0) e->command = json_string_value(json_arg); - else - e->arguments.push_back(json_string_value(json_arg)); + + e->arguments.push_back(json_string_value(json_arg)); } } From 9e418add405f0963c722a8d4afc85e1bc29c3675 Mon Sep 17 00:00:00 2001 From: Divya Laxetti Date: Wed, 26 Jun 2019 16:12:54 +0200 Subject: [PATCH 31/94] update common submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 39e23fc9a..38e66114a 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 39e23fc9a7234e7a235efd49e6cdc21ae370ed93 +Subproject commit 38e66114a9115f6da2486d14d2892e7c8be8142c From f71643813fa6fdff82365dce369369d4c21d210f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 20:18:02 +0200 Subject: [PATCH 32/94] fix several minor bugs detected by valgrind --- common | 2 +- etc/examples/nodes/exec.conf | 2 +- include/villas/node.h | 4 +-- lib/hooks/stats.cpp | 62 ++++++++++++++++-------------------- lib/nodes/exec.cpp | 8 +++-- lib/nodes/stats.cpp | 3 +- lib/stats.cpp | 9 ++++-- 7 files changed, 44 insertions(+), 46 deletions(-) diff --git a/common b/common index 38e66114a..04c94c4f9 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 38e66114a9115f6da2486d14d2892e7c8be8142c +Subproject commit 04c94c4f977a1b3cead342d4294afb39c5354adc diff --git a/etc/examples/nodes/exec.conf b/etc/examples/nodes/exec.conf index aee5328fc..ff336f5bf 100644 --- a/etc/examples/nodes/exec.conf +++ b/etc/examples/nodes/exec.conf @@ -3,7 +3,7 @@ nodes = { type = "exec" format = "villas.human" flush = true - exec = [ "tee test" ] + exec = "tee test" shell = true working_directory = "/tmp" environment = { diff --git a/include/villas/node.h b/include/villas/node.h index d1ae987d6..ecb988920 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -37,8 +37,8 @@ #include #include #include -#include #include +#include #if defined(LIBNL3_ROUTE_FOUND) && defined(__linux__) #define WITH_NETEM @@ -68,7 +68,7 @@ struct node { uint64_t sequence; /**< This is a counter of received samples, in case the node-type does not generate sequence numbers itself. */ - villas::Stats *stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ + std::shared_ptr stats; /**< Statistic counters. This is a pointer to the statistic hooks private data. */ struct node_direction in, out; diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp index 32ff01be5..b6bf63240 100644 --- a/lib/hooks/stats.cpp +++ b/lib/hooks/stats.cpp @@ -24,7 +24,7 @@ * @{ */ -#include +#include #include #include @@ -53,11 +53,9 @@ public: virtual Hook::Reason process(sample *smp) { - Stats *s = node->stats; - timespec now = time_now(); - s->update(Stats::Metric::AGE, time_delta(&smp->ts.received, &now)); + node->stats->update(Stats::Metric::AGE, time_delta(&smp->ts.received, &now)); return Reason::OK; } @@ -96,22 +94,20 @@ public: virtual Hook::Reason process(sample *smp) { - Stats *s = node->stats; - if (last) { if (smp->flags & last->flags & (int) SampleFlags::HAS_TS_RECEIVED) - s->update(Stats::Metric::GAP_RECEIVED, time_delta(&last->ts.received, &smp->ts.received)); + node->stats->update(Stats::Metric::GAP_RECEIVED, time_delta(&last->ts.received, &smp->ts.received)); if (smp->flags & last->flags & (int) SampleFlags::HAS_TS_ORIGIN) - s->update(Stats::Metric::GAP_SAMPLE, time_delta(&last->ts.origin, &smp->ts.origin)); + node->stats->update(Stats::Metric::GAP_SAMPLE, time_delta(&last->ts.origin, &smp->ts.origin)); if ((smp->flags & (int) SampleFlags::HAS_TS_ORIGIN) && (smp->flags & (int) SampleFlags::HAS_TS_RECEIVED)) - s->update(Stats::Metric::OWD, time_delta(&smp->ts.origin, &smp->ts.received)); + node->stats->update(Stats::Metric::OWD, time_delta(&smp->ts.origin, &smp->ts.received)); if (smp->flags & last->flags & (int) SampleFlags::HAS_SEQUENCE) { int dist = smp->sequence - (int32_t) last->sequence; if (dist != 1) - s->update(Stats::Metric::SMPS_REORDERED, dist); + node->stats->update(Stats::Metric::SMPS_REORDERED, dist); } } @@ -129,8 +125,6 @@ public: class StatsHook : public Hook { protected: - Stats stats; - StatsReadHook *readHook; StatsWriteHook *writeHook; @@ -139,26 +133,22 @@ protected: int warmup; int buckets; + std::shared_ptr stats; + AFILE *output; - char *uri; + std::string uri; public: StatsHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : Hook(p, n, fl, prio, en), - stats(buckets, warmup), format(Stats::Format::HUMAN), verbose(0), warmup(500), buckets(20), output(nullptr), - uri(nullptr) + uri() { - /* Register statistic object to path. - * - * This allows the path code to update statistics. */ - node->stats = &stats; - /* Add child hooks */ readHook = new StatsReadHook(p, n, fl, prio, en); writeHook = new StatsWriteHook(p, n, fl, prio, en); @@ -167,20 +157,12 @@ public: vlist_push(&node->out.hooks, (void *) writeHook); } - ~StatsHook() - { - if (uri) - free(uri); - - stats.~Stats(); - } - virtual void start() { assert(state == State::PREPARED); - if (uri) { - output = afopen(uri, "w+"); + if (!uri.empty()) { + output = afopen(uri.c_str(), "w+"); if (!output) throw RuntimeError("Failed to open file '{}' for writing", uri); } @@ -192,9 +174,9 @@ public: { assert(state == State::STARTED); - stats.print(uri ? output->file : stdout, format, verbose); + stats->print(uri.empty() ? stdout : output->file, format, verbose); - if (uri) + if (!uri.empty()) afclose(output); state = State::STOPPED; @@ -204,14 +186,14 @@ public: { assert(state == State::STARTED); - stats.reset(); + stats->reset(); } virtual void periodic() { assert(state == State::STARTED); - stats.printPeriodic(uri ? output->file : stdout, format, node); + stats->printPeriodic(uri.empty() ? stdout : output->file, format, node); } virtual void parse(json_t *cfg) @@ -243,10 +225,20 @@ public: } if (u) - uri = strdup(u); + uri = u; state = State::PARSED; } + + virtual void prepare() + { + stats = std::make_shared(buckets, warmup); + + /* Register statistic object to path. + * + * This allows the path code to update statistics. */ + node->stats = stats; + } }; /* Register hook */ diff --git a/lib/nodes/exec.cpp b/lib/nodes/exec.cpp index f9f890a1a..96e07fd30 100644 --- a/lib/nodes/exec.cpp +++ b/lib/nodes/exec.cpp @@ -141,9 +141,11 @@ int exec_destroy(struct node *n) int ret; struct exec *e = (struct exec *) n->_vd; - ret = io_destroy(&e->io); - if (ret) - return ret; + if (e->io.state == State::INITIALIZED) { + ret = io_destroy(&e->io); + if (ret) + return ret; + } return 0; } diff --git a/lib/nodes/stats.cpp b/lib/nodes/stats.cpp index d2c2a9dca..69e08acba 100644 --- a/lib/nodes/stats.cpp +++ b/lib/nodes/stats.cpp @@ -220,10 +220,9 @@ int stats_node_read(struct node *n, struct sample *smps[], unsigned cnt, unsigne unsigned len = MIN(vlist_length(&s->signals), smps[0]->capacity); for (size_t i = 0; i < len; i++) { - Stats *st; struct stats_node_signal *sig = (struct stats_node_signal *) vlist_at(&s->signals, i); - st = sig->node->stats; + auto st = sig->node->stats; if (!st) return -1; diff --git a/lib/stats.cpp b/lib/stats.cpp index b698a10ab..a6ebb73e1 100644 --- a/lib/stats.cpp +++ b/lib/stats.cpp @@ -104,8 +104,13 @@ enum Stats::Type Stats::lookupType(const std::string &str) Stats::Stats(int buckets, int warmup) { - for (auto m : metrics) - histograms[m.first] = Hist(buckets, warmup); + for (auto m : metrics) { + histograms.emplace( + std::piecewise_construct, + std::forward_as_tuple(m.first), + std::forward_as_tuple(buckets, warmup) + ); + } } void Stats::update(enum Metric m, double val) From 61eb669f0c2bbef82eba3f19aac28a0b01e473dc Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 20:37:47 +0200 Subject: [PATCH 33/94] tests: show elapsed time per test case --- tools/integration-tests.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/integration-tests.sh b/tools/integration-tests.sh index 2db8bfc30..f2b984437 100755 --- a/tools/integration-tests.sh +++ b/tools/integration-tests.sh @@ -83,6 +83,9 @@ echo -e "Starting integration tests for VILLASnode:\n" for TEST in ${TESTS}; do TESTNAME=$(basename -s .sh ${TEST}) + # Start time measurement + SECONDS=0 + # Run test if (( ${VERBOSE} == 0 )); then timeout ${TIMEOUT} ${TEST} &> ${LOGDIR}/${TESTNAME}.log @@ -91,6 +94,8 @@ for TEST in ${TESTS}; do timeout ${TIMEOUT} ${TEST} | tee ${LOGDIR}/${TESTNAME}.log RC=${PIPESTATUS[0]} fi + + TOTAL_SECONDS=${SECONDS} # Show full log in case of an error if (( ${VERBOSE} == 0 )); then @@ -101,7 +106,7 @@ for TEST in ${TESTS}; do case $RC in 0) - echo -e "\e[32m[PASS] \e[39m ${TESTNAME}" + echo -e "\e[32m[PASS] \e[39m ${TESTNAME} (ran for ${SECONDS} secs)" PASSED=$((${PASSED} + 1)) ;; 99) @@ -114,7 +119,7 @@ for TEST in ${TESTS}; do FAILED=$((${FAILED} + 1)) ;; *) - echo -e "\e[31m[FAIL] \e[39m ${TESTNAME} with code $RC" + echo -e "\e[31m[FAIL] \e[39m ${TESTNAME} (exited with code $RC, ran for ${SECONDS} secs)" FAILED=$((${FAILED} + 1)) ;; esac From af62dc20cadf46f5c30a2442022b278494150521 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 20:38:07 +0200 Subject: [PATCH 34/94] ci: use full concurency --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 54039741f..4f70b4f13 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ variables: DOCKER_TAG: ${CI_COMMIT_REF_NAME} DOCKER_IMAGE: villas/node DOCKER_IMAGE_DEV: villas/node-dev - MAKE_OPTS: -j 16 + MAKE_OPTS: -j $(nproc) LD_PRELOAD: /usr/lib64/libSegFault.so SEGFAULT_SIGNALS: all SEGFAULT_SIGNALS: bus abrt From 93ce39b3038ad3f729cc01f6d1af715255952a98 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 20:38:38 +0200 Subject: [PATCH 35/94] ci: allow package deployment also for non tagged commits --- .gitlab-ci.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4f70b4f13..43f98587f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,7 +8,7 @@ variables: DOCKER_TAG: ${CI_COMMIT_REF_NAME} DOCKER_IMAGE: villas/node DOCKER_IMAGE_DEV: villas/node-dev - MAKE_OPTS: -j $(nproc) + MAKE_OPTS: -j32 LD_PRELOAD: /usr/lib64/libSegFault.so SEGFAULT_SIGNALS: all SEGFAULT_SIGNALS: bus abrt @@ -99,9 +99,6 @@ build:docs: image: ${DOCKER_IMAGE_DEV}:${DOCKER_TAG} tags: - docker - only: - - tags - - master # Stage: test @@ -189,7 +186,7 @@ deploy:web: tags: - villas-deploy -deploy:packages: +.deploy:packages: &deploy_packages stage: deploy script: - ssh ${DEPLOY_USER}@${DEPLOY_HOST} mkdir -p ${DEPLOY_PATH}/{dist,../packages} @@ -200,5 +197,13 @@ deploy:packages: - packaging:rpm tags: - villas-deploy + +deploy:packages:manual: + <<: *deploy_packages + when: manual + +deploy:packages:manual: + <<: *deploy_packages only: - - tags + # Only on version tags + - "/^v\\d+(\\.\\d+)+$/" From 86aaaa9a205a10c919b87d1cdb6b8e2f3f50531a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 23:32:19 +0200 Subject: [PATCH 36/94] cmake: fix include dir for websockets --- lib/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index bba1d3745..7f598f82a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -67,6 +67,15 @@ set(LIB_SRC format_type.cpp ) +if(WITH_WEB) + list(APPEND LIB_SRC + web.cpp + ) + + list(APPEND INCLUDE_DIRS ${LIBWEBSOCKETS_INCLUDE_DIRS}) + list(APPEND LIBRARIES PkgConfig::LIBWEBSOCKETS) +endif() + if(WITH_NODE_INFINIBAND) list(APPEND LIB_SRC memory/ib.cpp) endif() @@ -92,15 +101,6 @@ if(WITH_HOOKS) list(APPEND WHOLE_ARCHIVES hooks) endif() -if(WITH_WEB) - list(APPEND LIB_SRC - web.cpp - ) - - list(APPEND INCLUDE_DIRS ${LIBWEBSOCKETS_INCLUDE_DIRS}) - list(APPEND LIBRARIES PkgConfig::LIBWEBSOCKETS) -endif() - if(WITH_API) list(APPEND LIB_SRC api.cpp From 2d818774e9575e3adfb32112dba304465e1323ae Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 23:32:41 +0200 Subject: [PATCH 37/94] ci: remove libSegfault from build stages --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 43f98587f..d4584b43f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -76,13 +76,11 @@ build:fedora-minimal:x86_64: build:ubuntu:x86_64: extends: build:fedora:x86_64 variables: - LD_PRELOAD: /lib/x86_64-linux-gnu/libSegFault.so DOCKER_IMAGE_DEV: villas/node-dev-ubuntu build:raspbian:armv6l: extends: build:fedora:x86_64 variables: - LD_PRELOAD: /lib/arm-linux-gnueabihf/libSegFault.so DOCKER_IMAGE_DEV: villas/node-dev-raspbian CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF From a9f85715774f795065d4964942ae32c8ed23bb9a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 23:33:20 +0200 Subject: [PATCH 38/94] docker: add Dockerfile for armhf cross-compilation based on Debian Buster / Multiarch --- cmake/toolchains/debian-armhf.cmake | 15 +++ packaging/docker/Dockerfile.dev-debian-armhf | 115 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 cmake/toolchains/debian-armhf.cmake create mode 100644 packaging/docker/Dockerfile.dev-debian-armhf diff --git a/cmake/toolchains/debian-armhf.cmake b/cmake/toolchains/debian-armhf.cmake new file mode 100644 index 000000000..4594efdd2 --- /dev/null +++ b/cmake/toolchains/debian-armhf.cmake @@ -0,0 +1,15 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR armv7l) + +set(TRIPLET "arm-linux-gnueabihf") + +# specify the cross compiler +SET(CMAKE_C_COMPILER "/usr/bin/${TRIPLET}-gcc") +SET(CMAKE_CXX_COMPILER "/usr/bin/${TRIPLET}-g++") + +set(CMAKE_C_FLAGS "-mfloat-abi=hard ${CMAKE_C_FLAGS}" CACHE STRING "Buildroot CFLAGS") +set(CMAKE_CXX_FLAGS "-mfloat-abi=hard ${CMAKE_CXX_FLAGS}" CACHE STRING "Buildroot CXXFLAGS") +set(CMAKE_EXE_LINKER_FLAGS " ${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "Buildroot LDFLAGS") + +set(CMAKE_LIBRARY_PATH "/usr/lib/${TRIPLET}") + diff --git a/packaging/docker/Dockerfile.dev-debian-armhf b/packaging/docker/Dockerfile.dev-debian-armhf new file mode 100644 index 000000000..47ba4109c --- /dev/null +++ b/packaging/docker/Dockerfile.dev-debian-armhf @@ -0,0 +1,115 @@ +# Dockerfile for VILLASnode development. +# +# This Dockerfile builds an image which contains all library dependencies +# and tools to build VILLASnode. +# However, VILLASnode itself it not part of the image. +# +# This image can be used for developing VILLASnode +# by running: +# make docker +# +# @author Steffen Vogel +# @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC +# @license GNU General Public License (version 3) +# +# VILLASnode +# +# 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 +# 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 . +################################################################################### + +# You can choose between Debian and Ubuntu here +FROM debian:buster + +ARG GIT_REV=unknown +ARG GIT_BRANCH=unknown +ARG VERSION=unknown +ARG VARIANT=unknown + +ENV DEBIAN_FRONTEND=noninteractive + +# Enable armhf architecture +RUN dpkg --add-architecture armhf + +# Toolchain +RUN apt-get update && apt-get install -y \ + crossbuild-essential-armhf \ + pkg-config cmake make ninja-build \ + texinfo git curl tar \ + protobuf-compiler protobuf-c-compiler + +# Dependencies +RUN apt-get update && apt-get install -y \ + libssl-dev:armhf \ + libprotobuf-dev:armhf \ + libprotobuf-c-dev:armhf \ + uuid-dev:armhf \ + libconfig-dev:armhf \ + libnl-3-dev libnl-route-3-dev:armhf \ + libcurl4-openssl-dev:armhf \ + libjansson-dev:armhf \ + libzmq3-dev:armhf \ + libnanomsg-dev:armhf \ + librabbitmq-dev:armhf \ + libmosquitto-dev:armhf \ + libcomedi-dev:armhf \ + libibverbs-dev:armhf \ + librdmacm-dev:armhf \ + libre-dev:armhf + +ADD cmake/toolchains/debian-armhf.cmake / + +ENV TRIPLET=arm-linux-gnueabihf +ENV PKG_CONFIG_PATH=/usr/lib/${TRIPLET}/pkgconfig:/usr/local/lib/pkgconfig:/usr/share/pkgconfig +ENV PKG_CONFIG_LIBDIR=/usr/lib/${TRIPLET}/pkgconfig:/usr/share/pkgconfig + +ENV CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=/debian-armhf.cmake \ + -DCMAKE_INSTALL_LIBDIR=/usr/lib/${TRIPLET} \ + -DOPENSSL_INCLUDE_DIR=/usr/include/${TRIPLET}/ \ + -DOPENSSL_CRYPTO_LIBRARY=/usr/lib/${TRIPLET}/libcrypto.so \ + -DOPENSSL_SSL_LIBRARY=/usr/lib/${TRIPLET}/libssl.so \ + -DCURL_INCLUDE_DIR=/usr/include/${TRIPLET}/ \ + -DCURL_LIBRARY=/usr/lib/${TRIPLET}/libcurl.so" + +# Build & Install libwebsockets +RUN cd /tmp && \ + git clone -b v3.1-stable https://github.com/warmcat/libwebsockets && \ + mkdir -p libwebsockets/build && cd libwebsockets/build && \ + cmake ${CMAKE_OPTS} -DLWS_INSTALL_LIB_DIR=lib/${TRIPLET} .. && make -j$(nproc) install && \ + rm -rf /tmp/* + +# Build & Install libiec61850 +RUN cd /tmp && \ + git clone -b v1.3.1 https://github.com/mz-automation/libiec61850 && \ + mkdir -p libiec61850/build && cd libiec61850/build && \ + cmake ${CMAKE_OPTS} .. && make -j$(nproc) install && \ + rm -rf /tmp/* + +WORKDIR /villas +ENTRYPOINT bash + +LABEL \ + org.label-schema.schema-version="1.0" \ + org.label-schema.name="VILLASnode" \ + org.label-schema.license="GPL-3.0" \ + org.label-schema.vcs-ref="$GIT_REV" \ + org.label-schema.vcs-branch="$GIT_BRANCH" \ + org.label-schema.version="$VERSION" \ + org.label-schema.variant="$VARIANT" \ + org.label-schema.vendor="Institute for Automation of Complex Power Systems, RWTH Aachen University" \ + org.label-schema.author.name="Steffen Vogel" \ + org.label-schema.author.email="stvogel@eonerc.rwth-aachen.de" \ + org.label-schema.description="A image containing all build-time dependencies for VILLASnode based on Ubuntu" \ + org.label-schema.url="http://fein-aachen.org/projects/villas-framework/" \ + org.label-schema.vcs-url="https://git.rwth-aachen.de/VILLASframework/VILLASnode" \ + org.label-schema.usage="https://villas.fein-aachen.org/doc/node-installation.html#node-installation-docker" From 5e3d5a49a0fd6ec559524f76f96da5d3e645b152 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 26 Jun 2019 23:33:41 +0200 Subject: [PATCH 39/94] ci: add cross-compile target --- .gitlab-ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d4584b43f..05290ae1f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,6 +44,12 @@ prepare:raspbian:docker-dev: DOCKER_FILE: packaging/docker/Dockerfile.dev-raspbian DOCKER_IMAGE_DEV: villas/node-dev-raspbian +prepare:debian-armhf:docker-dev: + extends: prepare:fedora:docker-dev + variables: + DOCKER_FILE: packaging/docker/Dockerfile.dev-debian-armhf + DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf + prepare:ubuntu:docker-dev: extends: prepare:fedora:docker-dev variables: @@ -84,6 +90,11 @@ build:raspbian:armv6l: DOCKER_IMAGE_DEV: villas/node-dev-raspbian CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF +build:debian-cross:armv7l: + extends: build:fedora:x86_64 + variables: + DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf + build:docs: stage: build artifacts: From 7a8b2b902df4e97a971cb608a6c3746c59afe64c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:25:25 +0200 Subject: [PATCH 40/94] ci: add support for armhf and aarch64 cross-builds --- .gitlab-ci.yml | 28 +++++--- cmake/toolchains/debian-arm64.cmake | 15 +++++ ...-armhf => Dockerfile.dev-debian-multiarch} | 65 ++++++++++--------- 3 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 cmake/toolchains/debian-arm64.cmake rename packaging/docker/{Dockerfile.dev-debian-armhf => Dockerfile.dev-debian-multiarch} (73%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 05290ae1f..f1faaadfd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,7 +31,7 @@ before_script: prepare:fedora:docker-dev: stage: prepare script: - - docker build + - docker build ${DOCKER_OPTS} --file ${DOCKER_FILE} --tag ${DOCKER_IMAGE_DEV}:${DOCKER_TAG} . tags: @@ -44,18 +44,25 @@ prepare:raspbian:docker-dev: DOCKER_FILE: packaging/docker/Dockerfile.dev-raspbian DOCKER_IMAGE_DEV: villas/node-dev-raspbian -prepare:debian-armhf:docker-dev: - extends: prepare:fedora:docker-dev - variables: - DOCKER_FILE: packaging/docker/Dockerfile.dev-debian-armhf - DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf - prepare:ubuntu:docker-dev: extends: prepare:fedora:docker-dev variables: DOCKER_FILE: packaging/docker/Dockerfile.dev-ubuntu DOCKER_IMAGE_DEV: villas/node-dev-ubuntu +prepare:debian-armhf:docker-dev: + extends: prepare:fedora:docker-dev + variables: + DOCKER_FILE: packaging/docker/Dockerfile.dev-debian-multiarch + DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf + DOCKER_OPTS: --build-arg ARCH=armhf --build-arg TRIPLET=arm-linux-gnueabihf + +prepare:debian-arm64:docker-dev: + extends: prepare:fedora:docker-dev + variables: + DOCKER_FILE: packaging/docker/Dockerfile.dev-debian-multiarch + DOCKER_IMAGE_DEV: villas/node-dev-debian-arm64 + DOCKER_OPTS: --build-arg ARCH=arm64 --build-arg TRIPLET=aarch64-linux-gnu # Stage: build ############################################################################## @@ -90,11 +97,16 @@ build:raspbian:armv6l: DOCKER_IMAGE_DEV: villas/node-dev-raspbian CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF -build:debian-cross:armv7l: +build:debian-multiarch:armhf: extends: build:fedora:x86_64 variables: DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf +build:debian-multiarch:arm64: + extends: build:fedora:x86_64 + variables: + DOCKER_IMAGE_DEV: villas/node-dev-debian-arm64 + build:docs: stage: build artifacts: diff --git a/cmake/toolchains/debian-arm64.cmake b/cmake/toolchains/debian-arm64.cmake new file mode 100644 index 000000000..0a3b553f0 --- /dev/null +++ b/cmake/toolchains/debian-arm64.cmake @@ -0,0 +1,15 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +set(TRIPLET "aarch64-linux-gnu") + +# specify the cross compiler +SET(CMAKE_C_COMPILER "/usr/bin/${TRIPLET}-gcc") +SET(CMAKE_CXX_COMPILER "/usr/bin/${TRIPLET}-g++") + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "Buildroot CFLAGS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "Buildroot CXXFLAGS") +set(CMAKE_EXE_LINKER_FLAGS " ${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "Buildroot LDFLAGS") + +set(CMAKE_LIBRARY_PATH "/usr/lib/${TRIPLET}") + diff --git a/packaging/docker/Dockerfile.dev-debian-armhf b/packaging/docker/Dockerfile.dev-debian-multiarch similarity index 73% rename from packaging/docker/Dockerfile.dev-debian-armhf rename to packaging/docker/Dockerfile.dev-debian-multiarch index 47ba4109c..e86b39c1e 100644 --- a/packaging/docker/Dockerfile.dev-debian-armhf +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -36,56 +36,54 @@ ARG GIT_BRANCH=unknown ARG VERSION=unknown ARG VARIANT=unknown +ARG ARCH=armhf +ARG TRIPLET=arm-linux-gnueabihf + ENV DEBIAN_FRONTEND=noninteractive -# Enable armhf architecture -RUN dpkg --add-architecture armhf +# Enable ${ARCH} architecture +RUN dpkg --add-architecture ${ARCH} # Toolchain RUN apt-get update && apt-get install -y \ - crossbuild-essential-armhf \ + crossbuild-essential-${ARCH} \ pkg-config cmake make ninja-build \ texinfo git curl tar \ protobuf-compiler protobuf-c-compiler # Dependencies RUN apt-get update && apt-get install -y \ - libssl-dev:armhf \ - libprotobuf-dev:armhf \ - libprotobuf-c-dev:armhf \ - uuid-dev:armhf \ - libconfig-dev:armhf \ - libnl-3-dev libnl-route-3-dev:armhf \ - libcurl4-openssl-dev:armhf \ - libjansson-dev:armhf \ - libzmq3-dev:armhf \ - libnanomsg-dev:armhf \ - librabbitmq-dev:armhf \ - libmosquitto-dev:armhf \ - libcomedi-dev:armhf \ - libibverbs-dev:armhf \ - librdmacm-dev:armhf \ - libre-dev:armhf + libssl-dev:${ARCH} \ + libprotobuf-dev:${ARCH} \ + libprotobuf-c-dev:${ARCH} \ + uuid-dev:${ARCH} \ + libconfig-dev:${ARCH} \ + libnl-3-dev libnl-route-3-dev:${ARCH} \ + libcurl4-openssl-dev:${ARCH} \ + libjansson-dev:${ARCH} \ + libzmq3-dev:${ARCH} \ + libnanomsg-dev:${ARCH} \ + librabbitmq-dev:${ARCH} \ + libmosquitto-dev:${ARCH} \ + libcomedi-dev:${ARCH} \ + libibverbs-dev:${ARCH} \ + librdmacm-dev:${ARCH} \ + libre-dev:${ARCH} \ + libusb-1.0-0-dev:${ARCH} -ADD cmake/toolchains/debian-armhf.cmake / +ADD cmake/toolchains/debian-${ARCH}.cmake / -ENV TRIPLET=arm-linux-gnueabihf ENV PKG_CONFIG_PATH=/usr/lib/${TRIPLET}/pkgconfig:/usr/local/lib/pkgconfig:/usr/share/pkgconfig ENV PKG_CONFIG_LIBDIR=/usr/lib/${TRIPLET}/pkgconfig:/usr/share/pkgconfig -ENV CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=/debian-armhf.cmake \ - -DCMAKE_INSTALL_LIBDIR=/usr/lib/${TRIPLET} \ - -DOPENSSL_INCLUDE_DIR=/usr/include/${TRIPLET}/ \ - -DOPENSSL_CRYPTO_LIBRARY=/usr/lib/${TRIPLET}/libcrypto.so \ - -DOPENSSL_SSL_LIBRARY=/usr/lib/${TRIPLET}/libssl.so \ - -DCURL_INCLUDE_DIR=/usr/include/${TRIPLET}/ \ - -DCURL_LIBRARY=/usr/lib/${TRIPLET}/libcurl.so" +ENV CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=/debian-${ARCH}.cmake \ + -DCMAKE_INSTALL_LIBDIR=/usr/lib/${TRIPLET}" # Build & Install libwebsockets RUN cd /tmp && \ git clone -b v3.1-stable https://github.com/warmcat/libwebsockets && \ mkdir -p libwebsockets/build && cd libwebsockets/build && \ - cmake ${CMAKE_OPTS} -DLWS_INSTALL_LIB_DIR=lib/${TRIPLET} .. && make -j$(nproc) install && \ + cmake ${CMAKE_OPTS} -DLWS_INSTALL_LIB_DIR=/usr/lib/${TRIPLET} .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install libiec61850 @@ -95,6 +93,15 @@ RUN cd /tmp && \ cmake ${CMAKE_OPTS} .. && make -j$(nproc) install && \ rm -rf /tmp/* +# Build & Install uldaq +RUN apt-get -y install automake autoconf libtool +RUN cd /tmp && \ + git clone -b rpm https://github.com/stv0g/uldaq && \ + mkdir -p uldaq/build && cd uldaq && \ + autoreconf -i && cd build && \ + ../configure --host=${TRIPLET} && make -j$(nproc) install && \ + rm -rf /tmp/* + WORKDIR /villas ENTRYPOINT bash From 688b731e2487335a2ddddc9fd94010f62588bd70 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:25:50 +0200 Subject: [PATCH 41/94] cmake: fix linking against libwebsockets --- lib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 7f598f82a..56e5d1ea8 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -73,7 +73,7 @@ if(WITH_WEB) ) list(APPEND INCLUDE_DIRS ${LIBWEBSOCKETS_INCLUDE_DIRS}) - list(APPEND LIBRARIES PkgConfig::LIBWEBSOCKETS) + list(APPEND LIBRARIES PkgConfig::LIBWEBSOCKETS ${LIBWEBSOCKETS_LDFLAGS}) endif() if(WITH_NODE_INFINIBAND) From 9e1220ae2075d3ecb367cd3c08a7af56f99f34b5 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:26:13 +0200 Subject: [PATCH 42/94] gate: add new gate hook for triggered acquisition --- lib/hooks/CMakeLists.txt | 3 +- lib/hooks/gate.cpp | 178 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 lib/hooks/gate.cpp diff --git a/lib/hooks/CMakeLists.txt b/lib/hooks/CMakeLists.txt index 13764a6f0..ddd867516 100644 --- a/lib/hooks/CMakeLists.txt +++ b/lib/hooks/CMakeLists.txt @@ -29,8 +29,10 @@ set(HOOK_SRC dump.cpp ebm.cpp fix.cpp + gate.cpp jitter_calc.cpp limit_rate.cpp + print.cpp restart.cpp scale.cpp shift_seq.cpp @@ -38,7 +40,6 @@ set(HOOK_SRC skip_first.cpp stats.cpp ts.cpp - print.cpp ) add_library(hooks STATIC ${HOOK_SRC}) diff --git a/lib/hooks/gate.cpp b/lib/hooks/gate.cpp new file mode 100644 index 000000000..b1155c6fe --- /dev/null +++ b/lib/hooks/gate.cpp @@ -0,0 +1,178 @@ +/** Gate hook. + * + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +/** @addtogroup hooks Hook functions + * @{ + */ + +#include +#include +#include + +#include +#include +#include + +namespace villas { +namespace node { + +class GateHook : public Hook { + +protected: + enum class Mode { + ABOVE, + BELOW, + RISING_EDGE, + FALLING_EDGE + } mode; + + std::string signalName; + int signalIndex; + double threshold; + double duration; + double previousValue; + +public: + GateHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : + Hook(p, n, fl, prio, en), + mode(Mode::RISING_EDGE), + threshold(0.5), + duration(1), + previousValue(std::numeric_limits::quiet_NaN()) + { } + + virtual void parse(json_t *cfg) + { + int ret; + + json_error_t err; + json_t *json_signal; + + const char *mode_str; + + assert(state != State::STARTED); + + ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: F, s?: F, s?: s }", + "signal", &json_signal, + "threshold", &threshold, + "duration", &duration, + "mode", &mode_str + ); + if (ret) + throw ConfigError(cfg, err, "node-config-hook-gate"); + + if (mode_str) { + if (!strcmp(mode_str, "above")) + mode = Mode::ABOVE; + else if (!strcmp(mode_str, "below")) + mode = Mode::BELOW; + else if (!strcmp(mode_str, "rising_edge")) + mode = Mode::RISING_EDGE; + else if (!strcmp(mode_str, "falling_edge")) + mode = Mode::FALLING_EDGE; + } + + switch (json_typeof(json_signal)) { + case JSON_STRING: + signalName = json_string_value(json_signal); + break; + + case JSON_INTEGER: + signalName.clear(); + signalIndex = json_integer_value(json_signal); + break; + + default: + throw ConfigError(json_signal, "node-config-hook-cast-signals", "Invalid value for setting 'signal'"); + } + + state = State::PARSED; + } + + virtual void prepare() + { + assert(state == State::CHECKED); + + if (!signalName.empty()) { + signalIndex = vlist_lookup_index(&signals, signalName.c_str()); + if (signalIndex < 0) + throw RuntimeError("Failed to find signal: {}", signalName); + } + + /* Check if signal type is float */ + auto sig = (struct signal *) vlist_at(&signals, signalIndex); + if (!sig) + throw RuntimeError("Invalid signal index: {}", signalIndex); + + if (sig->type != SignalType::FLOAT) + throw RuntimeError("Gate signal must be of type float"); + + state = State::PREPARED; + } + + + virtual Hook::Reason process(sample *smp) + { + assert(state == State::STARTED); + + double value = smp->data[signalIndex].f; + Hook::Reason reason; + + switch (mode) { + case Mode::ABOVE: + reason = value > threshold ? Reason::OK : Reason::SKIP_SAMPLE; + break; + + case Mode::BELOW: + reason = value < threshold ? Reason::OK : Reason::SKIP_SAMPLE; + break; + + case Mode::RISING_EDGE: + reason = (!std::isnan(previousValue) && value > previousValue) ? Reason::OK : Reason::SKIP_SAMPLE; + break; + + case Mode::FALLING_EDGE: + reason = (!std::isnan(previousValue) && value < previousValue) ? Reason::OK : Reason::SKIP_SAMPLE; + break; + + default: + reason = Reason::ERROR; + } + + previousValue = value; + + return reason; + } +}; + +/* Register hook */ +static HookPlugin p( + "gate", + "Skip samples only if an enable signal is under a specified threshold", + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::PATH, + 99 +); + +} /* namespace node */ +} /* namespace villas */ + +/** @} */ From a6ad231f7aeebf638dbc79c7689548649285efff Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:36:35 +0200 Subject: [PATCH 43/94] gate: add integration test --- tests/integration/hook-gate.sh | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100755 tests/integration/hook-gate.sh diff --git a/tests/integration/hook-gate.sh b/tests/integration/hook-gate.sh new file mode 100755 index 000000000..34417da57 --- /dev/null +++ b/tests/integration/hook-gate.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Integration test for gate hook. +# +# @author Steffen Vogel +# @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC +# @license GNU General Public License (version 3) +# +# VILLASnode +# +# 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 +# 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 . +################################################################################## + +INPUT_FILE=$(mktemp) +OUTPUT_FILE=$(mktemp) +EXPECT_FILE=$(mktemp) + +cat < ${INPUT_FILE} +# seconds.nanoseconds(sequence) random sine square triangle ramp +1561591854.277376100(0) 0.022245 -0.136359 1.000000 -0.912920 0.104354 +1561591854.377354600(1) 0.015339 0.135690 -1.000000 0.913350 0.204333 +1561591854.475834300(2) 0.027500 -0.088233 1.000000 -0.943756 0.302812 +1561591854.575995900(3) 0.040320 0.093289 -1.000000 0.940524 0.402974 +1561591854.675955300(4) 0.026079 -0.092019 1.000000 -0.941336 0.502933 +1561591854.776188900(5) 0.049262 0.099324 -1.000000 0.936664 0.603167 +1561591854.875119100(6) 0.014883 -0.065832 1.000000 -0.958060 0.702097 +1561591854.974264200(7) 0.023232 0.039012 -1.000000 0.975158 0.801242 +1561591855.077804200(8) 0.015231 -0.149670 1.000000 -0.904358 0.904782 +1561591855.174828300(9) 0.060849 0.056713 -1.000000 0.963876 1.001806 +EOF + +cat < ${EXPECT_FILE} +# seconds.nanoseconds+offset(sequence) signal0 signal1 signal2 signal3 signal4 +1561591854.277376100(0) 0.022245 -0.136359 1.000000 -0.912920 0.104354 +1561591854.475834300(2) 0.027500 -0.088233 1.000000 -0.943756 0.302812 +1561591854.675955300(4) 0.026079 -0.092019 1.000000 -0.941336 0.502933 +1561591854.875119100(6) 0.014883 -0.065832 1.000000 -0.958060 0.702097 +1561591855.077804200(8) 0.015231 -0.149670 1.000000 -0.904358 0.904782 +EOF + +villas-hook gate -o signal=2 -o mode=above < ${INPUT_FILE} > ${OUTPUT_FILE} + +# Compare only the data values +villas-test-cmp ${OUTPUT_FILE} ${EXPECT_FILE} +RC=$? + +rm -f ${INPUT_FILE} ${OUTPUT_FILE} ${EXPECT_FILE} + +exit $RC From cfc84c04574bca2c792ac34d1c0517617566c6e3 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:36:45 +0200 Subject: [PATCH 44/94] gate: add example config --- etc/examples/hooks/gate.conf | 19 +++++++++++++++++++ etc/examples/hooks/scale.conf | 18 ------------------ 2 files changed, 19 insertions(+), 18 deletions(-) create mode 100644 etc/examples/hooks/gate.conf diff --git a/etc/examples/hooks/gate.conf b/etc/examples/hooks/gate.conf new file mode 100644 index 000000000..96aac6e09 --- /dev/null +++ b/etc/examples/hooks/gate.conf @@ -0,0 +1,19 @@ +@include "hook-nodes.conf" + +paths = ( + { + in = "signal_node" + out = "file_node" + + hooks = ( + { + type = "gate" + + signal = "square" + mode = "above" + threshold = 0.5 + duration = 5 + } + ) + } +) diff --git a/etc/examples/hooks/scale.conf b/etc/examples/hooks/scale.conf index 68508707b..e69de29bb 100644 --- a/etc/examples/hooks/scale.conf +++ b/etc/examples/hooks/scale.conf @@ -1,18 +0,0 @@ -@include "hook-nodes.conf" - -paths = ( - { - in = "signal_node" - out = "file_node" - - hooks = ( - { - type = "scale" - - signal = "sine" - scale = 5.5 - offset = 1.2 - } - ) - } -) From 4ce98dd6fce1a9866cdef62afe79a68773b5ec37 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:38:09 +0200 Subject: [PATCH 45/94] update VILLAScommon submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 04c94c4f9..bf060238f 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 04c94c4f977a1b3cead342d4294afb39c5354adc +Subproject commit bf060238f6df57f886b7ce9e951ac6b1f2a0c6fd From 4038ec03bcb875f091b18df6446d6f1a294925e8 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:44:19 +0200 Subject: [PATCH 46/94] ci: limit libSegfault to tests only --- .gitlab-ci.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f1faaadfd..b5c386bdb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,9 +9,6 @@ variables: DOCKER_IMAGE: villas/node DOCKER_IMAGE_DEV: villas/node-dev MAKE_OPTS: -j32 - LD_PRELOAD: /usr/lib64/libSegFault.so - SEGFAULT_SIGNALS: all - SEGFAULT_SIGNALS: bus abrt stages: - prepare @@ -129,6 +126,10 @@ test:unit: stage: test dependencies: - build:fedora:x86_64 + variables: + LD_PRELOAD: /usr/lib64/libSegFault.so + SEGFAULT_SIGNALS: all + SEGFAULT_SIGNALS: bus abrt script: - mkdir -p build && cd build - cmake .. && make ${MAKE_OPTS} unit-tests @@ -141,6 +142,10 @@ test:integration: stage: test dependencies: - build:fedora:x86_64 + variables: + LD_PRELOAD: /usr/lib64/libSegFault.so + SEGFAULT_SIGNALS: all + SEGFAULT_SIGNALS: bus abrt script: - mkdir -p build && cd build - cmake .. From 2d7941ea1724a515852a83541621eaf7f9b4e6d4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 01:51:03 +0200 Subject: [PATCH 47/94] uldaq: fix compare of differing signedness --- lib/nodes/uldaq.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nodes/uldaq.cpp b/lib/nodes/uldaq.cpp index 4e7186c76..687f0999a 100644 --- a/lib/nodes/uldaq.cpp +++ b/lib/nodes/uldaq.cpp @@ -606,7 +606,7 @@ int uldaq_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *re if (u->in.status != SS_RUNNING) return -1; - long long start_index = u->in.buffer_pos; + size_t start_index = u->in.buffer_pos; /* Wait for data available condition triggered by event callback */ if (start_index + n->in.vectorize * u->in.channel_count > u->in.transfer_status.currentScanCount) From 32fcbdf796af56cfc4077e7eda8d05ed1e531cb0 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 02:20:58 +0200 Subject: [PATCH 48/94] gate: add hold-off timer --- lib/hooks/gate.cpp | 66 +++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/lib/hooks/gate.cpp b/lib/hooks/gate.cpp index b1155c6fe..39b30dd92 100644 --- a/lib/hooks/gate.cpp +++ b/lib/hooks/gate.cpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace villas { namespace node { @@ -49,15 +50,22 @@ protected: int signalIndex; double threshold; double duration; + int samples; double previousValue; + bool active; + uint64_t startSequence; + timespec startTime; + public: GateHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : Hook(p, n, fl, prio, en), mode(Mode::RISING_EDGE), threshold(0.5), - duration(1), - previousValue(std::numeric_limits::quiet_NaN()) + duration(-1), + samples(-1), + previousValue(std::numeric_limits::quiet_NaN()), + active(false) { } virtual void parse(json_t *cfg) @@ -71,10 +79,11 @@ public: assert(state != State::STARTED); - ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: F, s?: F, s?: s }", + ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: F, s?: F, s?: i, s?: s }", "signal", &json_signal, "threshold", &threshold, "duration", &duration, + "samples", &samples, "mode", &mode_str ); if (ret) @@ -134,28 +143,47 @@ public: { assert(state == State::STARTED); - double value = smp->data[signalIndex].f; Hook::Reason reason; + double value = smp->data[signalIndex].f; - switch (mode) { - case Mode::ABOVE: - reason = value > threshold ? Reason::OK : Reason::SKIP_SAMPLE; - break; + if (active) { + if (duration > 0 && time_delta(&smp->ts.origin, &startTime) < duration) + reason = Reason::OK; + else if (samples > 0 && smp->sequence - startSequence < (uint64_t) samples) + reason = Reason::OK; + else { + reason = Reason::SKIP_SAMPLE; + active = false; + } + } - case Mode::BELOW: - reason = value < threshold ? Reason::OK : Reason::SKIP_SAMPLE; - break; + if (!active) { + switch (mode) { + case Mode::ABOVE: + reason = value > threshold ? Reason::OK : Reason::SKIP_SAMPLE; + break; - case Mode::RISING_EDGE: - reason = (!std::isnan(previousValue) && value > previousValue) ? Reason::OK : Reason::SKIP_SAMPLE; - break; + case Mode::BELOW: + reason = value < threshold ? Reason::OK : Reason::SKIP_SAMPLE; + break; - case Mode::FALLING_EDGE: - reason = (!std::isnan(previousValue) && value < previousValue) ? Reason::OK : Reason::SKIP_SAMPLE; - break; + case Mode::RISING_EDGE: + reason = (!std::isnan(previousValue) && value > previousValue) ? Reason::OK : Reason::SKIP_SAMPLE; + break; - default: - reason = Reason::ERROR; + case Mode::FALLING_EDGE: + reason = (!std::isnan(previousValue) && value < previousValue) ? Reason::OK : Reason::SKIP_SAMPLE; + break; + + default: + reason = Reason::ERROR; + } + + if (reason == Reason::OK) { + startTime = smp->ts.origin; + startSequence = smp->sequence; + active = true; + } } previousValue = value; From 667901688a36f746aa95cf68dce665f365a59a3b Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 02:22:08 +0200 Subject: [PATCH 49/94] gate: add hold-off timer --- etc/examples/hooks/gate.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/etc/examples/hooks/gate.conf b/etc/examples/hooks/gate.conf index 96aac6e09..ac5467e8f 100644 --- a/etc/examples/hooks/gate.conf +++ b/etc/examples/hooks/gate.conf @@ -12,7 +12,10 @@ paths = ( signal = "square" mode = "above" threshold = 0.5 - duration = 5 + + # Once triggered, keep active for: + duration = 5 # in seconds + samples = 100 # in number of samples } ) } From bb3210faafe1f8d33cf18c213c2d32069c865e5a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 09:55:30 +0200 Subject: [PATCH 50/94] ci: allow failures in integration tests --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b5c386bdb..c274a4906 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -156,6 +156,7 @@ test:integration: paths: - build/tests/integration/ image: ${DOCKER_IMAGE_DEV}:${DOCKER_TAG} + allow_failure: true tags: - docker From ed26f772e749ea5e7762595af3dbf13b2698209a Mon Sep 17 00:00:00 2001 From: Divya Laxetti Date: Thu, 27 Jun 2019 15:45:45 +0200 Subject: [PATCH 51/94] memory locking without root --- lib/memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/memory.cpp b/lib/memory.cpp index 4bba823d6..f649ef872 100644 --- a/lib/memory.cpp +++ b/lib/memory.cpp @@ -77,7 +77,7 @@ int memory_lock(size_t lock) warning("Failed to in increase ressource limit of locked memory. Please increase manually by running as root:"); warning(" $ ulimit -Hl %zu", lock); - goto out; + return 0; } l.rlim_max = lock; @@ -91,7 +91,7 @@ int memory_lock(size_t lock) debug(LOG_MEM | 2, "Increased ressource limit of locked memory to %zd bytes", lock); } -out: + #endif /* __arm__ */ #ifdef _POSIX_MEMLOCK /* Lock all current and future memory allocations */ From fb401ae65b3d552e1ad1ec6d3663ee1e32f7798b Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 21:25:18 +0200 Subject: [PATCH 52/94] ci: build RPM packages in every commit --- .gitlab-ci.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c274a4906..917d61c9b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -193,9 +193,6 @@ packaging:rpm: image: ${DOCKER_IMAGE_DEV}:${DOCKER_TAG} tags: - docker - only: - - tags - - master # Stage: deploy ############################################################################## @@ -229,7 +226,7 @@ deploy:packages:manual: <<: *deploy_packages when: manual -deploy:packages:manual: +deploy:packages:tags: <<: *deploy_packages only: # Only on version tags From 8b046ad20b750c656621070943a56d0d3f3ff4eb Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 21:47:46 +0200 Subject: [PATCH 53/94] tests: reduce timeouts --- tools/integration-tests.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/integration-tests.sh b/tools/integration-tests.sh index f2b984437..4c8712a3a 100755 --- a/tools/integration-tests.sh +++ b/tools/integration-tests.sh @@ -37,7 +37,7 @@ export PATH SRCDIR BUILDDIR LOGDIR VERBOSE=${VERBOSE:-0} FILTER=${FILTER:-'*'} NUM_SAMPLES=${NUM_SAMPLES:-100} -TIMEOUT=${TIMEOUT:-5m} +TIMEOUT=${TIMEOUT:-2m} # Parse command line arguments while getopts ":f:l:t:v" OPT; do @@ -106,7 +106,7 @@ for TEST in ${TESTS}; do case $RC in 0) - echo -e "\e[32m[PASS] \e[39m ${TESTNAME} (ran for ${SECONDS} secs)" + echo -e "\e[32m[PASS] \e[39m ${TESTNAME} (ran for ${SECONDS}s)" PASSED=$((${PASSED} + 1)) ;; 99) @@ -114,12 +114,12 @@ for TEST in ${TESTS}; do SKIPPED=$((${SKIPPED} + 1)) ;; 124) - echo -e "\e[33m[TIME] \e[39m ${TESTNAME}" + echo -e "\e[33m[TIME] \e[39m ${TESTNAME} (ran for more then ${TIMEOUT})" TIMEDOUT=$((${TIMEDOUT} + 1)) FAILED=$((${FAILED} + 1)) ;; *) - echo -e "\e[31m[FAIL] \e[39m ${TESTNAME} (exited with code $RC, ran for ${SECONDS} secs)" + echo -e "\e[31m[FAIL] \e[39m ${TESTNAME} (exited with code $RC, ran for ${SECONDS}s)" FAILED=$((${FAILED} + 1)) ;; esac From 56c3db4bb15acf808b1e883dea3f6923ce38271d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 27 Jun 2019 22:15:20 +0200 Subject: [PATCH 54/94] ci: fix deployment of packages --- .gitlab-ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 917d61c9b..18a889515 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: DOCKER_IMAGE: villas/node DOCKER_IMAGE_DEV: villas/node-dev MAKE_OPTS: -j32 + RELEASEVER: 29 stages: - prepare @@ -213,10 +214,10 @@ deploy:web: .deploy:packages: &deploy_packages stage: deploy script: - - ssh ${DEPLOY_USER}@${DEPLOY_HOST} mkdir -p ${DEPLOY_PATH}/{dist,../packages} - - rsync ${RSYNC_OPTS} build/*.rpm ${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/../packages/x86_64/ - - rsync ${RSYNC_OPTS} build/*.tar.gz ${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/dist/ - - ssh ${DEPLOY_USER}@${DEPLOY_HOST} createrepo ${DEPLOY_PATH}/../packages + - ssh ${DEPLOY_USER}@${DEPLOY_HOST} mkdir -p $${DEPLOY_PATH_PACKAGES}/{fedora/x86_64,dist} + - rsync ${RSYNC_OPTS} build/*.tar.gz ${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH_PACKAGES}/dist/ + - rsync ${RSYNC_OPTS} build/*.rpm ${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH_PACKAGES}/fedora/${RELEASEVER}/x86_64 + - ssh ${DEPLOY_USER}@${DEPLOY_HOST} createrepo ${DEPLOY_PATH_PACKAGES}/fedora/${RELEASEVER}/x86_64 dependencies: - packaging:rpm tags: From 594105454ff62d5c483a4817210b7e92bd4d8a2f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 28 Jun 2019 11:49:00 +0200 Subject: [PATCH 55/94] ci: ix dependency for package building --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 18a889515..95f50f1f5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -180,7 +180,7 @@ packaging:docker: packaging:rpm: stage: packaging dependencies: - - build:docs + - build:fedora:x86_64 script: - mkdir -p build && cd build - cmake .. From e0f4fe74023994ef29af70ef532b55f691e91ab8 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 28 Jun 2019 13:37:01 +0200 Subject: [PATCH 56/94] ci: fix missing docs in install stage --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95f50f1f5..8d7d0a214 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -184,6 +184,7 @@ packaging:rpm: script: - mkdir -p build && cd build - cmake .. + - make ${MAKE_OPTS} doc - make ${MAKE_OPTS} package artifacts: expire_in: 1 week From 387918660cdf6d7573450277891bbf44931d4d27 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 28 Jun 2019 14:25:04 +0200 Subject: [PATCH 57/94] ci: run raspbian build only manually --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8d7d0a214..32825bb19 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -94,6 +94,7 @@ build:raspbian:armv6l: variables: DOCKER_IMAGE_DEV: villas/node-dev-raspbian CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF + when: manual build:debian-multiarch:armhf: extends: build:fedora:x86_64 From db15dda56611435546176780d48137c4f4d83559 Mon Sep 17 00:00:00 2001 From: Manuel Pitz Date: Tue, 30 Jul 2019 12:01:05 +0200 Subject: [PATCH 58/94] loopback: node type does not provide signals --- lib/nodes/loopback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nodes/loopback.cpp b/lib/nodes/loopback.cpp index 68e0e21b5..c90cd3a8e 100644 --- a/lib/nodes/loopback.cpp +++ b/lib/nodes/loopback.cpp @@ -164,7 +164,7 @@ static void register_plugin() { p.type = PluginType::NODE; p.node.instances.state = State::DESTROYED; p.node.vectorize = 0; - p.node.flags = (int) NodeFlags::PROVIDES_SIGNALS; + p.node.flags = 0; p.node.size = sizeof(struct loopback); p.node.parse = loopback_parse; p.node.print = loopback_print; From d7f9f7218fce48e3332c17ac24a9793767565559 Mon Sep 17 00:00:00 2001 From: Manuel Pitz Date: Tue, 30 Jul 2019 12:01:44 +0200 Subject: [PATCH 59/94] path: path_poll_prepare is not possible before nodes are started --- lib/path.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/path.cpp b/lib/path.cpp index 245082bac..dd3960b5a 100644 --- a/lib/path.cpp +++ b/lib/path.cpp @@ -148,6 +148,9 @@ int path_init(struct path *p) p->_name = nullptr; + p->reader.pfds = nullptr; + p->reader.nfds = 0; + /* Default values */ p->mode = PathMode::ANY; p->rate = 0; /* Disabled */ @@ -168,6 +171,9 @@ static int path_prepare_poll(struct path *p) { int fds[16], ret, n = 0, m; + if (p->reader.pfds) + free(p->reader.pfds); + p->reader.pfds = nullptr; p->reader.nfds = 0; @@ -297,13 +303,6 @@ int path_prepare(struct path *p) if (ret) return ret; - /* Prepare poll() */ - if (p->poll) { - ret = path_prepare_poll(p); - if (ret) - return ret; - } - if (p->original_sequence_no == -1) p->original_sequence_no = vlist_length(&p->sources) == 1; @@ -628,6 +627,15 @@ int path_start(struct path *p) p->last_sample->data[i] = sig->init; } + /* Prepare poll() */ + if (p->poll) { + ret = path_prepare_poll(p); + if (ret) + return ret; + } + + p->state = State::STARTED; + /* Start one thread per path for sending to destinations * * Special case: If the path only has a single source and this source @@ -638,8 +646,6 @@ int path_start(struct path *p) if (ret) return ret; - p->state = State::STARTED; - return 0; } From f9c03f51b62530025a59335406783e754186220c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 13 Aug 2019 21:22:13 +0200 Subject: [PATCH 60/94] added new hook for timestamping data according to GPS PPS signal --- lib/hooks/CMakeLists.txt | 3 +- lib/hooks/pps_ts.cpp | 142 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 lib/hooks/pps_ts.cpp diff --git a/lib/hooks/CMakeLists.txt b/lib/hooks/CMakeLists.txt index 13764a6f0..f2490f8aa 100644 --- a/lib/hooks/CMakeLists.txt +++ b/lib/hooks/CMakeLists.txt @@ -24,7 +24,7 @@ set(HOOK_SRC average.cpp cast.cpp decimate.cpp - dp.cpp + #dp.cpp drop.cpp dump.cpp ebm.cpp @@ -38,6 +38,7 @@ set(HOOK_SRC skip_first.cpp stats.cpp ts.cpp + pps_ts.cpp print.cpp ) diff --git a/lib/hooks/pps_ts.cpp b/lib/hooks/pps_ts.cpp new file mode 100644 index 000000000..fa5ea693c --- /dev/null +++ b/lib/hooks/pps_ts.cpp @@ -0,0 +1,142 @@ +/** Timestamp hook. + * + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +/** @addtogroup hooks Hook functions + * @{ + */ + +#include +#include +#include + +#include + +namespace villas { +namespace node { + +class PpsTsHook : public Hook { + +protected: + double lastValue; + double thresh; + double realSmpRate; + unsigned idx; + int lastSeqNr; + unsigned edgeCounter; + + timespec realTime; + +public: + PpsTsHook(struct path *p, struct node *n, int fl, int prio, bool en = true) : + Hook(p, n, fl, prio, en), + lastValue(0), + thresh(1.5), + realSmpRate(0), + idx(0), + lastSeqNr(0), + edgeCounter(0), + realTime({ 0, 0 }) + { + } + + virtual void parse(json_t *cfg) + { + int ret; + json_error_t err; + + assert(state != STATE_STARTED); + + ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s?: f }", + "signal_index", &idx, + "threshold", &thresh + ); + if (ret) + throw ConfigError(cfg, err, "node-config-hook-pps_ts"); + + info("parsed config thresh=%f signal_index=%d", thresh, idx); + + state = STATE_PARSED; + } + + virtual int process(sample *smp) + { + assert(state == STATE_STARTED); + + /* Get value of PPS signal */ + float value = smp->data[idx].f; // TODO check if it is really float + int seqNr = smp->sequence; + + /* Detect Edge */ + bool isEdge = lastValue < thresh && value > thresh; + if (isEdge) { + if (edgeCounter >= 1) + realSmpRate = seqNr - lastSeqNr; + if (edgeCounter == 1) { + auto now = time_now(); + + if (now.tv_nsec >= 0.5e9) + realTime.tv_sec = now.tv_sec + 1; + else + realTime.tv_sec = now.tv_sec; + } + + lastSeqNr = seqNr; + + info("Edge detected: seq=%u, realTime.sec=%ld, realTime.nsec=%ld, smpRate=%f", seqNr, realTime.tv_sec, realTime.tv_nsec, realSmpRate); + + edgeCounter++; + } + + lastValue = value; + + if (edgeCounter < 2) + return HOOK_SKIP_SAMPLE; + else if (edgeCounter == 2 && isEdge) + realTime.tv_nsec = 0; + else + realTime.tv_nsec += 1e9 / realSmpRate; + + if (realTime.tv_nsec >= 1000000000) { + realTime.tv_sec++; + realTime.tv_nsec -= 1000000000; + } + + /* Update timestamp */ + smp->ts.origin = realTime; + smp->flags |= SAMPLE_HAS_TS_ORIGIN; + + return HOOK_OK; + } +}; + +/* Register hook */ +static HookPlugin p( + "pps_ts", + "Timestamp samples based GPS PPS signal", + HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + 99 +); + +} /* namespace node */ +} /* namespace villas */ + +/** @} */ From a3c8b17665a6706e8ce9bd25394e167f8775a52d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 28 Aug 2019 16:55:40 +0200 Subject: [PATCH 61/94] web: reduce polling timeout for lws_service --- lib/web.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web.cpp b/lib/web.cpp index de2db734f..8b60c1484 100644 --- a/lib/web.cpp +++ b/lib/web.cpp @@ -170,7 +170,7 @@ void Web::worker() logger->info("Started worker"); while (running) { - lws_service(context, 100); + lws_service(context, 10); while (!writables.empty()) { wsi = writables.pop(); From bbe01d0bd2d4413c2de103af3ea98fcaa7e0cc5e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 28 Aug 2019 16:56:22 +0200 Subject: [PATCH 62/94] stats: fix state assertions in stats hook --- lib/hooks/stats.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp index b6bf63240..94696e402 100644 --- a/lib/hooks/stats.cpp +++ b/lib/hooks/stats.cpp @@ -232,12 +232,16 @@ public: virtual void prepare() { + assert(state == State::CHECKED); + stats = std::make_shared(buckets, warmup); /* Register statistic object to path. * * This allows the path code to update statistics. */ node->stats = stats; + + state = State::PREPARED; } }; From 287f2497359e4068342e07cf526eb90ef8e1271b Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 29 Aug 2019 09:59:04 +0200 Subject: [PATCH 63/94] msg: fix intiialization of reserved fields --- lib/formats/msg.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/formats/msg.cpp b/lib/formats/msg.cpp index 44acd2dad..b871cbc4e 100644 --- a/lib/formats/msg.cpp +++ b/lib/formats/msg.cpp @@ -110,6 +110,8 @@ int msg_from_sample(struct msg *msg_in, struct sample *smp, struct vlist *signal { msg_in->type = MSG_TYPE_DATA; msg_in->version = MSG_VERSION; + msg_in->rsvd1 = 0; + msg_in->resv2 = 0; msg_in->length = (uint16_t) smp->length; msg_in->sequence = (uint32_t) smp->sequence; msg_in->ts.sec = smp->ts.origin.tv_sec; From db1621dbace15bbfa7512aacfebcbdd823039cd3 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 21:05:43 +0200 Subject: [PATCH 64/94] python: bump and upload new version to pypi.org --- python/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/setup.py b/python/setup.py index f2259cdeb..0cdfb202d 100644 --- a/python/setup.py +++ b/python/setup.py @@ -7,7 +7,7 @@ with open('README.md') as f: setup( name = 'villas-node', - version = '0.6.4.1', + version = '0.6.5', author = 'Steffen Vogel', author_email = 'acs-software@eonerc.rwth-aachen.de', description = 'Python-support for VILLASnode simulation-data gateway', From 5e6fec26ae1775ece36d7e43d36891736fdadb30 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 21:21:11 +0200 Subject: [PATCH 65/94] signal: refactor signal_data_snprint() -> signal_data_print_str() --- include/villas/signal.h | 2 +- lib/formats/csv.cpp | 2 +- lib/formats/villas_human.cpp | 2 +- lib/signal.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/villas/signal.h b/include/villas/signal.h index 33989f5ba..8e33d3303 100644 --- a/include/villas/signal.h +++ b/include/villas/signal.h @@ -134,7 +134,7 @@ enum SignalType signal_type_detect(const char *val); void signal_data_cast(union signal_data *data, const struct signal *from, const struct signal *to); /** Print value of a signal to a character buffer. */ -int signal_data_snprint(const union signal_data *data, const struct signal *sig, char *buf, size_t len); +int signal_data_print_str(const union signal_data *data, const struct signal *sig, char *buf, size_t len); int signal_data_parse_str(union signal_data *data, const struct signal *sig, const char *ptr, char **end); diff --git a/lib/formats/csv.cpp b/lib/formats/csv.cpp index 64ef38634..26b82d0df 100644 --- a/lib/formats/csv.cpp +++ b/lib/formats/csv.cpp @@ -66,7 +66,7 @@ static size_t csv_sprint_single(struct io *io, char *buf, size_t len, const stru break; off += snprintf(buf + off, len - off, "%c", io->separator); - off += signal_data_snprint(&smp->data[i], sig, buf + off, len - off); + off += signal_data_print_str(&smp->data[i], sig, buf + off, len - off); } } diff --git a/lib/formats/villas_human.cpp b/lib/formats/villas_human.cpp index f34880a99..f573a4f06 100644 --- a/lib/formats/villas_human.cpp +++ b/lib/formats/villas_human.cpp @@ -62,7 +62,7 @@ static size_t villas_human_sprint_single(struct io *io, char *buf, size_t len, c break; off += snprintf(buf + off, len - off, "%c", io->separator); - off += signal_data_snprint(&smp->data[i], sig, buf + off, len - off); + off += signal_data_print_str(&smp->data[i], sig, buf + off, len - off); } } diff --git a/lib/signal.cpp b/lib/signal.cpp index 0478d114a..a60e06383 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -338,7 +338,7 @@ void signal_list_dump(const struct vlist *list, const union signal_data *data, u if (data && i < len) { char val[32]; - signal_data_snprint(&data[i], sig, val, sizeof(val)); + signal_data_print_str(&data[i], sig, val, sizeof(val)); strcatf(&buf, " = %s", val); } @@ -652,7 +652,7 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js return 0; } -int signal_data_snprint(const union signal_data *data, const struct signal *sig, char *buf, size_t len) +int signal_data_print_str(const union signal_data *data, const struct signal *sig, char *buf, size_t len) { switch (sig->type) { case SignalType::FLOAT: From 6c6f580f1d6ed5a08e84661d964dcbdaf42bada0 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 21:32:55 +0200 Subject: [PATCH 66/94] update common submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index bf060238f..73325386e 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit bf060238f6df57f886b7ce9e951ac6b1f2a0c6fd +Subproject commit 73325386ee0183f9f1748feebabb0404dca1d29a From 3aab1611ce0491f4f92e2e8ee381e04034058531 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 21:40:20 +0200 Subject: [PATCH 67/94] add missing spdlog to Dockerfiles --- packaging/docker/Dockerfile.dev | 3 ++- packaging/docker/Dockerfile.dev-centos | 3 ++- packaging/docker/Dockerfile.dev-debian-multiarch | 3 ++- packaging/docker/Dockerfile.dev-raspbian | 3 ++- packaging/docker/Dockerfile.dev-ubuntu | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packaging/docker/Dockerfile.dev b/packaging/docker/Dockerfile.dev index 4ddf903e7..7901f5ecf 100644 --- a/packaging/docker/Dockerfile.dev +++ b/packaging/docker/Dockerfile.dev @@ -83,7 +83,8 @@ RUN dnf -y install \ libibverbs-devel \ librdmacm-devel \ re-devel \ - uldaq-devel + uldaq-devel \ + spdlog-devel # Build & Install Criterion RUN cd /tmp && \ diff --git a/packaging/docker/Dockerfile.dev-centos b/packaging/docker/Dockerfile.dev-centos index da6393d70..2535797b9 100644 --- a/packaging/docker/Dockerfile.dev-centos +++ b/packaging/docker/Dockerfile.dev-centos @@ -91,7 +91,8 @@ RUN yum -y install \ libibverbs-devel \ librdmacm-devel \ re-devel \ - uldaq-devel + uldaq-devel \ + spdlog-devel # Build & Install Criterion RUN cd /tmp && \ diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index e86b39c1e..7f10591ef 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -69,7 +69,8 @@ RUN apt-get update && apt-get install -y \ libibverbs-dev:${ARCH} \ librdmacm-dev:${ARCH} \ libre-dev:${ARCH} \ - libusb-1.0-0-dev:${ARCH} + libusb-1.0-0-dev:${ARCH} \ + libspdlog-dev:${ARCH} ADD cmake/toolchains/debian-${ARCH}.cmake / diff --git a/packaging/docker/Dockerfile.dev-raspbian b/packaging/docker/Dockerfile.dev-raspbian index 9cc1e39a8..667636cf5 100644 --- a/packaging/docker/Dockerfile.dev-raspbian +++ b/packaging/docker/Dockerfile.dev-raspbian @@ -51,7 +51,8 @@ RUN apt-get install -y\ libcomedi-dev \ librdmacm-dev \ libre-dev \ - libusb-1.0-0-dev + libusb-1.0-0-dev \ + libspdlog-dev ENV CC=gcc ENV CXX=g++ diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu index c41a3d8b6..3dbe673e3 100644 --- a/packaging/docker/Dockerfile.dev-ubuntu +++ b/packaging/docker/Dockerfile.dev-ubuntu @@ -78,7 +78,8 @@ RUN apt-get update && apt-get install -y \ libcomedi-dev \ libibverbs-dev \ librdmacm-dev \ - libre-dev + libre-dev \ + libspdlog-dev # Build & Install Criterion RUN cd /tmp && \ From 9cbcef4fc1e119b8d07f6f3637f5ce04ed3b5ff6 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 22:02:42 +0200 Subject: [PATCH 68/94] format: do not use hyphens in file names --- include/villas/formats/{json-reserve.h => json_reserve.h} | 0 lib/formats/json_reserve.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename include/villas/formats/{json-reserve.h => json_reserve.h} (100%) diff --git a/include/villas/formats/json-reserve.h b/include/villas/formats/json_reserve.h similarity index 100% rename from include/villas/formats/json-reserve.h rename to include/villas/formats/json_reserve.h diff --git a/lib/formats/json_reserve.cpp b/lib/formats/json_reserve.cpp index 1a98b8112..b0102b796 100644 --- a/lib/formats/json_reserve.cpp +++ b/lib/formats/json_reserve.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #define JSON_RESERVE_INTEGER_TARGET 1 From fd3c732771d6f1d38e048ecc00db2efffa94c24f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 22:06:23 +0200 Subject: [PATCH 69/94] refactor: msg format reserved --- clients/hypersim/model/ucm_node.def | 7 ++++--- clients/opal/models/send_receive/include/msg_format.h | 4 ++-- clients/opal/models/send_receive/src/main.c | 3 ++- clients/opal/models/send_receive/src/msg.c | 2 +- include/villas/formats/msg_format.h | 6 +++--- lib/formats/msg.cpp | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/clients/hypersim/model/ucm_node.def b/clients/hypersim/model/ucm_node.def index 95b994383..88e3ea826 100644 --- a/clients/hypersim/model/ucm_node.def +++ b/clients/hypersim/model/ucm_node.def @@ -568,9 +568,9 @@ struct msg #if BYTE_ORDER == BIG_ENDIAN unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned reserved1 : 2; /**< Reserved bits */ #elif BYTE_ORDER == LITTLE_ENDIAN - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned reserved1 : 2; /**< Reserved bits */ unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ #else @@ -730,7 +730,8 @@ struct sockaddr_in rec_addr; msg->version = MSG_VERSION; msg->type = MSG_TYPE_DATA; - msg->rsvd1 = 0; + msg->reserved1 = 0; + msg->reserved2 = 0; msg->id = 0; msg->length = NO_SEND_DATA; msg->sequence = sequence++; diff --git a/clients/opal/models/send_receive/include/msg_format.h b/clients/opal/models/send_receive/include/msg_format.h index 29d9e4191..716965d8c 100644 --- a/clients/opal/models/send_receive/include/msg_format.h +++ b/clients/opal/models/send_receive/include/msg_format.h @@ -66,9 +66,9 @@ struct msg #if BYTE_ORDER == BIG_ENDIAN unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned reserved1 : 2; /**< Reserved bits */ #elif BYTE_ORDER == LITTLE_ENDIAN - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned reserved1 : 2; /**< Reserved bits */ unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ #else diff --git a/clients/opal/models/send_receive/src/main.c b/clients/opal/models/send_receive/src/main.c index 8de588595..b1191b55c 100644 --- a/clients/opal/models/send_receive/src/main.c +++ b/clients/opal/models/send_receive/src/main.c @@ -118,7 +118,8 @@ static void * SendToIPPort(void *arg) msg->version = MSG_VERSION; msg->type = MSG_TYPE_DATA; - msg->rsvd1 = 0; + msg->reserved1 = 0; + msg->reserved2 = 0; msg->id = SendID; msg->length = cnt; msg->sequence = Sequence++; diff --git a/clients/opal/models/send_receive/src/msg.c b/clients/opal/models/send_receive/src/msg.c index b61572f22..2a9f1341f 100644 --- a/clients/opal/models/send_receive/src/msg.c +++ b/clients/opal/models/send_receive/src/msg.c @@ -63,7 +63,7 @@ int msg_verify(struct msg *m) return -1; else if (m->type != MSG_TYPE_DATA) return -2; - else if (m->rsvd1 != 0) + else if (m->reserved1 != 0) return -3; else return 0; diff --git a/include/villas/formats/msg_format.h b/include/villas/formats/msg_format.h index b9da5952f..a1a4c9898 100644 --- a/include/villas/formats/msg_format.h +++ b/include/villas/formats/msg_format.h @@ -56,16 +56,16 @@ struct msg #if BYTE_ORDER == BIG_ENDIAN unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned reserved1 : 2; /**< Reserved bits */ #elif BYTE_ORDER == LITTLE_ENDIAN - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned reserved1 : 2; /**< Reserved bits */ unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ #else #error Invalid byte-order #endif - uint8_t resv2; /**< An id which identifies the source of this sample. */ + uint8_t reserved2; /**< An id which identifies the source of this sample. */ uint16_t length; /**< The number of values in msg::data[]. */ uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. */ diff --git a/lib/formats/msg.cpp b/lib/formats/msg.cpp index 44acd2dad..44d1f163d 100644 --- a/lib/formats/msg.cpp +++ b/lib/formats/msg.cpp @@ -67,7 +67,7 @@ int msg_verify(struct msg *m) return -1; else if (m->type != MSG_TYPE_DATA) return -2; - else if (m->rsvd1 != 0) + else if (m->reserved1 != 0) return -3; else return 0; From 1673368c0bb2b28d26651b6ecc50cd6f59298baa Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 22:26:34 +0200 Subject: [PATCH 70/94] ci: update Raspbian test image to Buster --- packaging/docker/Dockerfile.dev-raspbian | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packaging/docker/Dockerfile.dev-raspbian b/packaging/docker/Dockerfile.dev-raspbian index 667636cf5..5e4ee0815 100644 --- a/packaging/docker/Dockerfile.dev-raspbian +++ b/packaging/docker/Dockerfile.dev-raspbian @@ -20,7 +20,7 @@ # along with this program. If not, see . ################################################################################### -FROM balenalib/rpi-raspbian +FROM balenalib/rpi-raspbian:buster ARG GIT_REV=unknown ARG GIT_BRANCH=unknown @@ -29,7 +29,7 @@ ARG VARIANT=unknown # Toolchain RUN apt-get update && apt-get install -y \ - autoconf automake libtool \ + autoconf automake libtool cmake \ pkg-config make gcc g++\ git curl wget tar bzip2 \ protobuf-compiler protobuf-c-compiler @@ -57,14 +57,6 @@ RUN apt-get install -y\ ENV CC=gcc ENV CXX=g++ -# Build & Install CMake 3.14.1 -RUN cd /tmp && \ - wget https://github.com/Kitware/CMake/releases/download/v3.14.1/cmake-3.14.1.tar.gz && \ - tar -xzf cmake-3.14.1.tar.gz && \ - cd cmake-3.14.1 && ./bootstrap --parallel=$(nproc) -- -DCMAKE_BUILD_TYPE:STRING=Release && \ - make -j$(nproc) && make install && \ - rm -rf /tmp/* - # Add CMake install dir to PATH ENV PATH="usr/local/bin:${PATH}" From e1e9b2e1fc690b8fa478ec92273922f7fa0fcd4d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 22:54:10 +0200 Subject: [PATCH 71/94] format: fix parsing of complex values in villas.humas format (closes #261) --- lib/signal.cpp | 22 ++++++---- tests/unit/CMakeLists.txt | 3 +- tests/unit/signal.cpp | 87 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 tests/unit/signal.cpp diff --git a/lib/signal.cpp b/lib/signal.cpp index a60e06383..972d69f79 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -585,7 +585,7 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con break; case SignalType::COMPLEX: { - float real, imag; + float real, imag = 0; real = strtod(ptr, end); if (*end == ptr) @@ -593,14 +593,22 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con ptr = *end; - imag = strtod(ptr, end); - if (*end == ptr) - return -1; + if (*ptr == 'i' || *ptr == 'j') { + imag = real; + real = 0; - if (**end != 'i') - return -1; + (*end)++; + } + else if (*ptr == '-' || *ptr == '+') { + imag = strtod(ptr, end); + if (*end == ptr) + return -1; - (*end)++; + if (**end != 'i' && **end != 'j') + return -1; + + (*end)++; + } data->z = std::complex(real, imag); break; diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 2cab31ca5..1a099de33 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -30,13 +30,14 @@ set(TEST_SRC pool.cpp queue.cpp queue_signalled.cpp + signal.cpp ) add_executable(unit-tests ${TEST_SRC}) target_link_libraries(unit-tests PUBLIC PkgConfig::CRITERION - villas Threads::Threads + villas ) add_custom_target(run-unit-tests diff --git a/tests/unit/signal.cpp b/tests/unit/signal.cpp new file mode 100644 index 000000000..1bf3a51a4 --- /dev/null +++ b/tests/unit/signal.cpp @@ -0,0 +1,87 @@ +/** Unit tests for memory management + * + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +#include + +#include + +extern void init_memory(); + +Test(signal, parse, .init = init_memory) { + int ret; + struct signal sig; + union signal_data sd; + const char *str; + char *end; + + + str = "1"; + sig.type = SignalType::INTEGER; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_eq(sd.i, 1); + + str = "1.2"; + sig.type = SignalType::FLOAT; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(sd.f, 1.2, 1e-6); + + str = "1"; + sig.type = SignalType::BOOLEAN; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_eq(sd.b, 1); + + str = "1"; + sig.type = SignalType::COMPLEX; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(std::real(sd.z), 1, 1e-6); + cr_assert_float_eq(std::imag(sd.z), 0, 1e-6); + + str = "-1-3i"; + sig.type = SignalType::COMPLEX; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(std::real(sd.z), -1, 1e-6); + cr_assert_float_eq(std::imag(sd.z), -3, 1e-6); + + str = "-3i"; + sig.type = SignalType::COMPLEX; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(std::real(sd.z), 0, 1e-6); + cr_assert_float_eq(std::imag(sd.z), -3, 1e-6); +} From 4a4a8e3d389b2acc0acfc88a4208c96c9d3c9cc8 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 22:59:40 +0200 Subject: [PATCH 72/94] upadte common submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 73325386e..94cc21779 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 73325386ee0183f9f1748feebabb0404dca1d29a +Subproject commit 94cc21779654ed19317bcccc3fa4853d4fdd1eac From 7feddca89760229dcc6bd91dee5450a7b01a6804 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 23:03:20 +0200 Subject: [PATCH 73/94] update common submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 94cc21779..f79f1b18e 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 94cc21779654ed19317bcccc3fa4853d4fdd1eac +Subproject commit f79f1b18ecc85472c6d8f62833616c2ea493d6b8 From 29ac5a7eae8e4ba86cd782714402e4c288e5bdc9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 23:03:32 +0200 Subject: [PATCH 74/94] add missing fmt library --- packaging/docker/Dockerfile.dev-debian-multiarch | 3 ++- packaging/docker/Dockerfile.dev-raspbian | 3 ++- packaging/docker/Dockerfile.dev-ubuntu | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 7f10591ef..9efeb5775 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -70,7 +70,8 @@ RUN apt-get update && apt-get install -y \ librdmacm-dev:${ARCH} \ libre-dev:${ARCH} \ libusb-1.0-0-dev:${ARCH} \ - libspdlog-dev:${ARCH} + libspdlog-dev:${ARCH} \ + libfmt-dev ADD cmake/toolchains/debian-${ARCH}.cmake / diff --git a/packaging/docker/Dockerfile.dev-raspbian b/packaging/docker/Dockerfile.dev-raspbian index 5e4ee0815..da1fd4139 100644 --- a/packaging/docker/Dockerfile.dev-raspbian +++ b/packaging/docker/Dockerfile.dev-raspbian @@ -52,7 +52,8 @@ RUN apt-get install -y\ librdmacm-dev \ libre-dev \ libusb-1.0-0-dev \ - libspdlog-dev + libspdlog-dev \ + libfmt-dev ENV CC=gcc ENV CXX=g++ diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu index 3dbe673e3..0c728ff06 100644 --- a/packaging/docker/Dockerfile.dev-ubuntu +++ b/packaging/docker/Dockerfile.dev-ubuntu @@ -79,7 +79,8 @@ RUN apt-get update && apt-get install -y \ libibverbs-dev \ librdmacm-dev \ libre-dev \ - libspdlog-dev + libspdlog-dev \ + libfmt-dev # Build & Install Criterion RUN cd /tmp && \ From bc67e865aa50338abfbd72ba1ea1c1e019183d1f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 23:14:38 +0200 Subject: [PATCH 75/94] add missing arch to dockerfile --- packaging/docker/Dockerfile.dev-debian-multiarch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 9efeb5775..804c754d5 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -71,7 +71,7 @@ RUN apt-get update && apt-get install -y \ libre-dev:${ARCH} \ libusb-1.0-0-dev:${ARCH} \ libspdlog-dev:${ARCH} \ - libfmt-dev + libfmt-dev:${ARCH} ADD cmake/toolchains/debian-${ARCH}.cmake / From 69d29cd33515ea398d506961f328ac9162a3f808 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 23:29:29 +0200 Subject: [PATCH 76/94] update common submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index f79f1b18e..743040ac5 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit f79f1b18ecc85472c6d8f62833616c2ea493d6b8 +Subproject commit 743040ac5407c9d9d57cc6f329267d3cb5ae1a9d From 93980ab72f3ce26050a00b954efab8a778f6da93 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 3 Sep 2019 23:57:22 +0200 Subject: [PATCH 77/94] docker: install spdlog and fmtlib from sources --- packaging/docker/Dockerfile.dev-ubuntu | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu index 0c728ff06..b1fd71caf 100644 --- a/packaging/docker/Dockerfile.dev-ubuntu +++ b/packaging/docker/Dockerfile.dev-ubuntu @@ -78,9 +78,23 @@ RUN apt-get update && apt-get install -y \ libcomedi-dev \ libibverbs-dev \ librdmacm-dev \ - libre-dev \ - libspdlog-dev \ - libfmt-dev + libre-dev + +# Build & Install fmtlib +RUN cd /tmp && \ + git clone --recursive https://github.com/fmtlib/fmt.git && \ + mkdir -p fmt/build && cd fmt/build && \ + git checkout 6.0.0 && \ + cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 .. && make -j$(nproc) install && \ + rm -rf /tmp/* + +# Build & Install spdlog +RUN cd /tmp && \ + git clone --recursive https://github.com/gabime/spdlog.git && \ + mkdir -p spdlog/build && cd spdlog/build && \ + git checkout v1.3.1 && \ + cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + rm -rf /tmp/* # Build & Install Criterion RUN cd /tmp && \ From be863894d86170b1bf9091336154adbd43b942a4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Wed, 4 Sep 2019 00:21:04 +0200 Subject: [PATCH 78/94] cmake: fix search path --- .gitlab-ci.yml | 18 ++++++++++----- .../docker/Dockerfile.dev-debian-multiarch | 22 +++++++++++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 32825bb19..35ea2d488 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -65,7 +65,7 @@ prepare:debian-arm64:docker-dev: # Stage: build ############################################################################## -build:fedora:x86_64: +build:base: stage: build script: - mkdir -p build && cd build @@ -79,32 +79,38 @@ build:fedora:x86_64: tags: - docker +build:fedora:x86_64: + extends: build:base + build:fedora-minimal:x86_64: - extends: build:fedora:x86_64 + extends: build:base variables: CMAKE_OPTS: -DWITH_HOOKS=OFF -DWITH_WEB=OFF -DWITH_API=OFF -DWITH_CONFIG=OFF -DWITH_SRC=OFF -DWITH_TOOLS=OFF -DWITH_TESTS=OFF -DWITH_PLUGINS=OFF -DWITH_CLIENTS=OFF -DWITH_DOC=OFF build:ubuntu:x86_64: - extends: build:fedora:x86_64 + extends: build:base variables: DOCKER_IMAGE_DEV: villas/node-dev-ubuntu + CMAKE_OPTS: -DCMAKE_MODULE_PATH=/usr/local/lib64/cmake -DCMAKE_PREFIX_PATH=/usr/local build:raspbian:armv6l: - extends: build:fedora:x86_64 + extends: build:base variables: DOCKER_IMAGE_DEV: villas/node-dev-raspbian CMAKE_OPTS: -DWITH_NODE_INFINIBAND=OFF when: manual build:debian-multiarch:armhf: - extends: build:fedora:x86_64 + extends: build:base variables: DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf + CMAKE_OPTS: -DCMAKE_MODULE_PATH=/usr/local/lib64/cmake -DCMAKE_PREFIX_PATH=/usr/local build:debian-multiarch:arm64: - extends: build:fedora:x86_64 + extends: build:base variables: DOCKER_IMAGE_DEV: villas/node-dev-debian-arm64 + CMAKE_OPTS: -DCMAKE_MODULE_PATH=/usr/local/lib64/cmake -DCMAKE_PREFIX_PATH=/usr/local build:docs: stage: build diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 804c754d5..828a129cb 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -69,9 +69,7 @@ RUN apt-get update && apt-get install -y \ libibverbs-dev:${ARCH} \ librdmacm-dev:${ARCH} \ libre-dev:${ARCH} \ - libusb-1.0-0-dev:${ARCH} \ - libspdlog-dev:${ARCH} \ - libfmt-dev:${ARCH} + libusb-1.0-0-dev:${ARCH} ADD cmake/toolchains/debian-${ARCH}.cmake / @@ -79,7 +77,23 @@ ENV PKG_CONFIG_PATH=/usr/lib/${TRIPLET}/pkgconfig:/usr/local/lib/pkgconfig:/usr/ ENV PKG_CONFIG_LIBDIR=/usr/lib/${TRIPLET}/pkgconfig:/usr/share/pkgconfig ENV CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=/debian-${ARCH}.cmake \ - -DCMAKE_INSTALL_LIBDIR=/usr/lib/${TRIPLET}" + -DCMAKE_INSTALL_LIBDIR=/usr/lib/${TRIPLET}" + +# Build & Install fmtlib +RUN cd /tmp && \ + git clone --recursive https://github.com/fmtlib/fmt.git && \ + mkdir -p fmt/build && cd fmt/build && \ + git checkout 6.0.0 && \ + cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 .. && make -j$(nproc) install && \ + rm -rf /tmp/* + +# Build & Install spdlog +RUN cd /tmp && \ + git clone --recursive https://github.com/gabime/spdlog.git && \ + mkdir -p spdlog/build && cd spdlog/build && \ + git checkout v1.3.1 && \ + cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + rm -rf /tmp/* # Build & Install libwebsockets RUN cd /tmp && \ From 1127278e90113614445c32774b6ff699d8491f86 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 16 Sep 2019 10:42:21 +0200 Subject: [PATCH 79/94] remove custom install path for libfmt and libspdlog to enable cmake finding cmake configs --- packaging/docker/Dockerfile.dev-debian-multiarch | 4 ++-- packaging/docker/Dockerfile.dev-ubuntu | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 828a129cb..8cdc737e6 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -84,7 +84,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ git checkout 6.0.0 && \ - cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 .. && make -j$(nproc) install && \ + cmake .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install spdlog @@ -92,7 +92,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/gabime/spdlog.git && \ mkdir -p spdlog/build && cd spdlog/build && \ git checkout v1.3.1 && \ - cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + cmake -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install libwebsockets diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu index b1fd71caf..c2b7942c2 100644 --- a/packaging/docker/Dockerfile.dev-ubuntu +++ b/packaging/docker/Dockerfile.dev-ubuntu @@ -85,7 +85,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ git checkout 6.0.0 && \ - cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 .. && make -j$(nproc) install && \ + cmake .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install spdlog @@ -93,7 +93,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/gabime/spdlog.git && \ mkdir -p spdlog/build && cd spdlog/build && \ git checkout v1.3.1 && \ - cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + cmake -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install Criterion From 2101fa5fa8e5790288516530f3428ba3f5c49289 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 16 Sep 2019 15:59:42 +0200 Subject: [PATCH 80/94] update common submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index 743040ac5..43fd33c9c 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 743040ac5407c9d9d57cc6f329267d3cb5ae1a9d +Subproject commit 43fd33c9c77db22b93f65c92a1acb25c141d42a3 From ef4c252c2e69d3905b960db046b88aba98ec78e8 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 16 Sep 2019 16:03:45 +0200 Subject: [PATCH 81/94] compile FMT as shared library, use external FMT lib in SPDLOG --- packaging/docker/Dockerfile.dev-debian-multiarch | 4 ++-- packaging/docker/Dockerfile.dev-ubuntu | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 8cdc737e6..72e07adc3 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -84,7 +84,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ git checkout 6.0.0 && \ - cmake .. && make -j$(nproc) install && \ + cmake -DBUILD_SHARED_LIBS=1 .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install spdlog @@ -92,7 +92,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/gabime/spdlog.git && \ mkdir -p spdlog/build && cd spdlog/build && \ git checkout v1.3.1 && \ - cmake -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + cmake -DCMAKE_BUILD_TYPE=Release -DSPDLOG_FMT_EXTERNAL=1 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install libwebsockets diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu index c2b7942c2..f42acf526 100644 --- a/packaging/docker/Dockerfile.dev-ubuntu +++ b/packaging/docker/Dockerfile.dev-ubuntu @@ -85,7 +85,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ git checkout 6.0.0 && \ - cmake .. && make -j$(nproc) install && \ + cmake -DBUILD_SHARED_LIBS=1 .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install spdlog @@ -93,7 +93,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/gabime/spdlog.git && \ mkdir -p spdlog/build && cd spdlog/build && \ git checkout v1.3.1 && \ - cmake -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + cmake -DCMAKE_BUILD_TYPE=Release -DSPDLOG_FMT_EXTERNAL=1 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install Criterion From 51e2f584df3ebbc5c748cecbfeebfaeffbf05cd5 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 16 Sep 2019 16:06:47 +0200 Subject: [PATCH 82/94] reduce version of FMT lib to 5.2.0 instead of 6.0.0 for compatibility with spdlog library --- packaging/docker/Dockerfile.dev-debian-multiarch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 72e07adc3..936f547f8 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -83,7 +83,7 @@ ENV CMAKE_OPTS="-DCMAKE_TOOLCHAIN_FILE=/debian-${ARCH}.cmake \ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ - git checkout 6.0.0 && \ + git checkout 5.2.0 && \ cmake -DBUILD_SHARED_LIBS=1 .. && make -j$(nproc) install && \ rm -rf /tmp/* From 3cfc2736aabe995f21e7ef6f6b71caa3a9091f50 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 16 Sep 2019 16:08:01 +0200 Subject: [PATCH 83/94] reduce version of FMT lib to 5.2.0 instead of 6.0.0 for compatibility with spdlog library --- packaging/docker/Dockerfile.dev-ubuntu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu index f42acf526..8e998d414 100644 --- a/packaging/docker/Dockerfile.dev-ubuntu +++ b/packaging/docker/Dockerfile.dev-ubuntu @@ -84,7 +84,7 @@ RUN apt-get update && apt-get install -y \ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ - git checkout 6.0.0 && \ + git checkout 5.2.0 && \ cmake -DBUILD_SHARED_LIBS=1 .. && make -j$(nproc) install && \ rm -rf /tmp/* From 37914a0af125fd2e090dbefa0dfbfb8c3b7e511f Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 17 Sep 2019 10:23:06 +0200 Subject: [PATCH 84/94] set LD_LIBRARY_PATH in debian multiarch --- packaging/docker/Dockerfile.dev-debian-multiarch | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 936f547f8..86aff02cd 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -118,6 +118,8 @@ RUN cd /tmp && \ ../configure --host=${TRIPLET} && make -j$(nproc) install && \ rm -rf /tmp/* +ENV LD_LIBRARY_PATH /usr/local/lib:/usr/lib:/usr/lib/${TRIPLET} + WORKDIR /villas ENTRYPOINT bash From f8fe445623af2ca9ba421b3241c8d020d5f533ed Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Tue, 17 Sep 2019 12:32:54 +0200 Subject: [PATCH 85/94] fixes for multiarch: - install cmake 3.15.3. binaries from github (older version in buster has a bug!) - use CMAKE_OPTS flag for compiling fmt and spdlog - use the cmake TOOLCHAIN file and INSTALL_LIBDIR fitting to the architecture in build stage --- .gitlab-ci.yml | 4 ++-- .../docker/Dockerfile.dev-debian-multiarch | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 35ea2d488..0c21162a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -104,13 +104,13 @@ build:debian-multiarch:armhf: extends: build:base variables: DOCKER_IMAGE_DEV: villas/node-dev-debian-armhf - CMAKE_OPTS: -DCMAKE_MODULE_PATH=/usr/local/lib64/cmake -DCMAKE_PREFIX_PATH=/usr/local + CMAKE_OPTS: -DCMAKE_TOOLCHAIN_FILE=/debian-armhf.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/arm-linux-gnueabihf build:debian-multiarch:arm64: extends: build:base variables: DOCKER_IMAGE_DEV: villas/node-dev-debian-arm64 - CMAKE_OPTS: -DCMAKE_MODULE_PATH=/usr/local/lib64/cmake -DCMAKE_PREFIX_PATH=/usr/local + CMAKE_OPTS: -DCMAKE_TOOLCHAIN_FILE=/debian-arm64.cmake -DCMAKE_INSTALL_LIBDIR=/usr/lib/aarch64-linux-gnu build:docs: stage: build diff --git a/packaging/docker/Dockerfile.dev-debian-multiarch b/packaging/docker/Dockerfile.dev-debian-multiarch index 86aff02cd..a04855684 100644 --- a/packaging/docker/Dockerfile.dev-debian-multiarch +++ b/packaging/docker/Dockerfile.dev-debian-multiarch @@ -47,8 +47,8 @@ RUN dpkg --add-architecture ${ARCH} # Toolchain RUN apt-get update && apt-get install -y \ crossbuild-essential-${ARCH} \ - pkg-config cmake make ninja-build \ - texinfo git curl tar \ + pkg-config make ninja-build \ + texinfo git curl tar wget\ protobuf-compiler protobuf-c-compiler # Dependencies @@ -71,6 +71,13 @@ RUN apt-get update && apt-get install -y \ libre-dev:${ARCH} \ libusb-1.0-0-dev:${ARCH} +# Install cmake (version from buster has a bug) +RUN cd /tmp && \ + wget https://github.com/Kitware/CMake/releases/download/v3.15.3/cmake-3.15.3-Linux-x86_64.sh && \ + chmod +x cmake-3.15.3-Linux-x86_64.sh && \ + ./cmake-3.15.3-Linux-x86_64.sh --skip-license --prefix=/usr && \ + rm -rf /tmp/* + ADD cmake/toolchains/debian-${ARCH}.cmake / ENV PKG_CONFIG_PATH=/usr/lib/${TRIPLET}/pkgconfig:/usr/local/lib/pkgconfig:/usr/share/pkgconfig @@ -84,7 +91,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/fmtlib/fmt.git && \ mkdir -p fmt/build && cd fmt/build && \ git checkout 5.2.0 && \ - cmake -DBUILD_SHARED_LIBS=1 .. && make -j$(nproc) install && \ + cmake ${CMAKE_OPTS} -DBUILD_SHARED_LIBS=1 .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install spdlog @@ -92,7 +99,7 @@ RUN cd /tmp && \ git clone --recursive https://github.com/gabime/spdlog.git && \ mkdir -p spdlog/build && cd spdlog/build && \ git checkout v1.3.1 && \ - cmake -DCMAKE_BUILD_TYPE=Release -DSPDLOG_FMT_EXTERNAL=1 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ + cmake ${CMAKE_OPTS} -DCMAKE_BUILD_TYPE=Release -DSPDLOG_FMT_EXTERNAL=1 -DSPDLOG_BUILD_BENCH=OFF .. && make -j$(nproc) install && \ rm -rf /tmp/* # Build & Install libwebsockets @@ -118,8 +125,6 @@ RUN cd /tmp && \ ../configure --host=${TRIPLET} && make -j$(nproc) install && \ rm -rf /tmp/* -ENV LD_LIBRARY_PATH /usr/local/lib:/usr/lib:/usr/lib/${TRIPLET} - WORKDIR /villas ENTRYPOINT bash From f3db8f6192609932016c095bef5e2f143d32cad6 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Wed, 8 May 2019 14:10:55 +0200 Subject: [PATCH 86/94] add unthreaded version of MQTT node type --- include/villas/nodes/mqtt_unthreaded.hpp | 49 ++++ lib/nodes/CMakeLists.txt | 2 +- lib/nodes/mqtt_unthreaded.cpp | 339 +++++++++++++++++++++++ 3 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 include/villas/nodes/mqtt_unthreaded.hpp create mode 100644 lib/nodes/mqtt_unthreaded.cpp diff --git a/include/villas/nodes/mqtt_unthreaded.hpp b/include/villas/nodes/mqtt_unthreaded.hpp new file mode 100644 index 000000000..4b9a37af1 --- /dev/null +++ b/include/villas/nodes/mqtt_unthreaded.hpp @@ -0,0 +1,49 @@ +/** Node type: mqtt_unthreaded + * + * @file + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +/** + * @addtogroup mqtt_unthreaded mqtt unthreaded node type + * @ingroup node + * @{ + */ + +#pragma once + +#include + +/** @see node_type::open */ +int mqtt_unthreaded_start(struct node *n); + +/** @see node_type::close */ +int mqtt_unthreaded_stop(struct node *n); + +/** @see node_type::read */ +int mqtt_unthreaded_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release); + +/** @see node_type::write */ +int mqtt_unthreaded_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release); + +/** perform MQTT network operations */ +int mqtt_unthreaded_loop(struct node *n); + +/** @} */ diff --git a/lib/nodes/CMakeLists.txt b/lib/nodes/CMakeLists.txt index 516743f66..db8759a8d 100644 --- a/lib/nodes/CMakeLists.txt +++ b/lib/nodes/CMakeLists.txt @@ -126,7 +126,7 @@ endif() # Enable MQTT support if(WITH_NODE_MQTT) - list(APPEND NODE_SRC mqtt.cpp) + list(APPEND NODE_SRC mqtt.cpp mqtt_unthreaded.cpp) list(APPEND INCLUDE_DIRS ${MOSQUITTO_INCLUDE_DIRS}) list(APPEND LIBRARIES ${MOSQUITTO_LIBRARIES}) endif() diff --git a/lib/nodes/mqtt_unthreaded.cpp b/lib/nodes/mqtt_unthreaded.cpp new file mode 100644 index 000000000..dafaefabb --- /dev/null +++ b/lib/nodes/mqtt_unthreaded.cpp @@ -0,0 +1,339 @@ +/** Node type: mqtt_unthreaded + * + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 + * 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 . + *********************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +static void mqtt_unthreaded_log_cb(struct mosquitto *mosq, void *userdata, int level, const char *str) +{ + switch (level) { + case MOSQ_LOG_NONE: + case MOSQ_LOG_INFO: + case MOSQ_LOG_NOTICE: + info("MQTT: %s", str); + break; + + case MOSQ_LOG_WARNING: + warning("MQTT: %s", str); + break; + + case MOSQ_LOG_ERR: + error("MQTT: %s", str); + break; + + case MOSQ_LOG_DEBUG: + debug(5, "MQTT: %s", str); + break; + } +} + + +static void mqtt_unthreaded_connect_cb(struct mosquitto *mosq, void *userdata, int result) +{ + struct node *n = (struct node *) userdata; + struct mqtt *m = (struct mqtt *) n->_vd; + + int ret; + + info("MQTT: Node %s connected to broker %s", node_name(n), m->host); + + if (m->subscribe) { + ret = mosquitto_subscribe(m->client, nullptr, m->subscribe, m->qos); + if (ret) + warning("MQTT: failed to subscribe to topic '%s' for node %s: %s", m->subscribe, node_name(n), mosquitto_strerror(ret)); + } + else + warning("MQTT: no subscribe for node %s as no subscribe topic is given", node_name(n)); + + mqtt_unthreaded_loop(n); +} + +static void mqtt_unthreaded_message_cb(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg) +{ + int ret; + struct node *n = (struct node *) userdata; + struct mqtt *m = (struct mqtt *) n->_vd; + struct sample *smps[n->in.vectorize]; + + debug(5, "MQTT: Node %s received a message of %d bytes from broker %s", node_name(n), msg->payloadlen, m->host); + + ret = sample_alloc_many(&m->pool, smps, n->in.vectorize); + if (ret <= 0) { + warning("Pool underrun in subscriber of %s", node_name(n)); + return; + } + + ret = io_sscan(&m->io, (char *) msg->payload, msg->payloadlen, nullptr, smps, n->in.vectorize); + if (ret < 0) { + warning("MQTT: Node %s received an invalid message", node_name(n)); + warning(" Payload: %s", (char *) msg->payload); + return; + } + if (ret == 0) { + debug(4, "MQTT: skip empty message for node %s", node_name(n)); + sample_decref_many(smps, n->in.vectorize); + return; + } + + queue_signalled_push_many(&m->queue, (void **) smps, n->in.vectorize); + mqtt_unthreaded_loop(n); +} + +static void mqtt_unthreaded_disconnect_cb(struct mosquitto *mosq, void *userdata, int result) +{ + struct node *n = (struct node *) userdata; + struct mqtt *m = (struct mqtt *) n->_vd; + + info("MQTT: Node %s disconnected from broker %s", node_name(n), m->host); +} + + +static void mqtt_unthreaded_subscribe_cb(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos) +{ + struct node *n = (struct node *) userdata; + struct mqtt *m = (struct mqtt *) n->_vd; + + info("MQTT: Node %s subscribed to broker %s", node_name(n), m->host); + n->state=STATE_STARTED; +} + +int mqtt_unthreaded_check(struct node *n) +{ + int ret; + struct mqtt *m = (struct mqtt *) n->_vd; + + ret = mosquitto_sub_topic_check(m->subscribe); + if (ret != MOSQ_ERR_SUCCESS) + error("Invalid subscribe topic: '%s' for node %s: %s", m->subscribe, node_name(n), mosquitto_strerror(ret)); + + ret = mosquitto_pub_topic_check(m->publish); + if (ret != MOSQ_ERR_SUCCESS) + error("Invalid publish topic: '%s' for node %s: %s", m->publish, node_name(n), mosquitto_strerror(ret)); + + return 0; +} + + + +int mqtt_unthreaded_start(struct node *n) +{ + int ret; + struct mqtt *m = (struct mqtt *) n->_vd; + + m->client = mosquitto_new(n->name, 0, (void *) n); + if (!m->client) + return -1; + + if (m->username && m->password) { + ret = mosquitto_username_pw_set(m->client, m->username, m->password); + if (ret) + goto mosquitto_error; + } + + if (m->ssl.enabled) { + ret = mosquitto_tls_set(m->client, m->ssl.cafile, m->ssl.capath, m->ssl.certfile, m->ssl.keyfile, nullptr); + if (ret) + goto mosquitto_error; + + ret = mosquitto_tls_insecure_set(m->client, m->ssl.insecure); + if (ret) + goto mosquitto_error; + } + + mosquitto_log_callback_set(m->client, mqtt_unthreaded_log_cb); + mosquitto_connect_callback_set(m->client, mqtt_unthreaded_connect_cb); + mosquitto_disconnect_callback_set(m->client, mqtt_unthreaded_disconnect_cb); + mosquitto_message_callback_set(m->client, mqtt_unthreaded_message_cb); + mosquitto_subscribe_callback_set(m->client, mqtt_unthreaded_subscribe_cb); + + ret = io_init(&m->io, m->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); + if (ret) + return ret; + + ret = io_check(&m->io); + if (ret) + return ret; + + ret = pool_init(&m->pool, 1024, SAMPLE_LENGTH(vlist_length(&n->in.signals)), &memory_hugepage); + if (ret) + return ret; + + ret = queue_signalled_init(&m->queue, 1024, &memory_hugepage, 0); + if (ret) + return ret; + + ret = mosquitto_connect(m->client, m->host, m->port, m->keepalive); + if (ret) + goto mosquitto_error; + + //The following while loop exists upon completion of subscibe procedure + while(n->state == STATE_PREPARED){ + mqtt_unthreaded_loop(n); + } + + return 0; + +mosquitto_error: + warning("MQTT: %s", mosquitto_strerror(ret)); + + return ret; +} + +int mqtt_unthreaded_stop(struct node *n) +{ + int ret; + struct mqtt *m = (struct mqtt *) n->_vd; + + ret = mosquitto_disconnect(m->client); + if (ret) + goto mosquitto_error; + + ret = io_destroy(&m->io); + if (ret) + return ret; + + return 0; + +mosquitto_error: + warning("MQTT: %s", mosquitto_strerror(ret)); + + return ret; +} + +int mqtt_unthreaded_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release) +{ + int pulled=0; + mqtt_unthreaded_loop(n); + + if(cnt > 0){ + struct mqtt *m = (struct mqtt *) n->_vd; + struct sample *smpt[cnt]; + pulled = queue_signalled_pull_many(&m->queue, (void **) smpt, cnt); + + sample_copy_many(smps, smpt, pulled); + sample_decref_many(smpt, pulled); + } + return pulled; +} + +int mqtt_unthreaded_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release) +{ + int ret; + struct mqtt *m = (struct mqtt *) n->_vd; + + size_t wbytes; + + char data[1500]; + + ret = io_sprint(&m->io, data, sizeof(data), &wbytes, smps, cnt); + if (ret < 0) + return ret; + + if (m->publish) { + ret = mosquitto_publish(m->client, nullptr /* mid */, m->publish, wbytes, data, m->qos, m->retain); + if (ret != MOSQ_ERR_SUCCESS) { + warning("MQTT: publish failed for node %s: %s", node_name(n), mosquitto_strerror(ret)); + return -abs(ret); + } + } + else + warning("MQTT: no publish for node %s possible because no publish topic is given", node_name(n)); + + mqtt_unthreaded_loop(n); + + return cnt; +} + +int mqtt_unthreaded_loop(struct node *n){ + + int ret; + struct mqtt *m = (struct mqtt *) n->_vd; + + //Carry out network operations in a synchronous way. + ret = mosquitto_loop(m->client, 0, 1); + if(ret){ + warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(n), mosquitto_strerror(ret)); + ret = mosquitto_reconnect(m->client); + if(ret != MOSQ_ERR_SUCCESS){ + error("MQTT: reconnection to broker failed for node %s: %s", node_name(n), mosquitto_strerror(ret)); + } + else{ + warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(n), mosquitto_strerror(ret)); + } + ret = mosquitto_loop(m->client, -1, 1); + if(ret != MOSQ_ERR_SUCCESS){ + error("MQTT: persisting connection error for node %s: %s", node_name(n), mosquitto_strerror(ret)); + } + } + + return 0; +} + +int mqtt_unthreaded_poll_fds(struct node *n, int fds[]) +{ + struct mqtt *m = (struct mqtt *) n->_vd; + + fds[0] = queue_signalled_fd(&m->queue); + + return 1; +} + +static struct plugin p; + +__attribute__((constructor(110))) +static void register_plugin() { + if (plugins.state == STATE_DESTROYED) + vlist_init(&plugins); + + p.name = "mqtt_unthreaded"; + p.description = "Message Queuing Telemetry Transport (libmosquitto), unthreaded variant"; + p.type = PLUGIN_TYPE_NODE; + p.node.instances.state = STATE_DESTROYED; + p.node.vectorize = 0; + p.node.size = sizeof(struct mqtt); + p.node.type.start = mqtt_type_start; + p.node.type.stop = mqtt_type_stop; + p.node.destroy = mqtt_destroy; + p.node.parse = mqtt_parse; + p.node.check = mqtt_unthreaded_check; + p.node.print = mqtt_print; + p.node.start = mqtt_unthreaded_start; + p.node.stop = mqtt_unthreaded_stop; + p.node.read = mqtt_unthreaded_read; + p.node.write = mqtt_unthreaded_write; + p.node.reverse = mqtt_reverse; + p.node.poll_fds = mqtt_unthreaded_poll_fds; + + vlist_init(&p.node.instances); + vlist_push(&plugins, &p); +} + +__attribute__((destructor(110))) +static void deregister_plugin() { + if (plugins.state != STATE_DESTROYED) + vlist_remove_all(&plugins, &p); +} From 19523377f4543ef711a84fde409f0ceac7b4bfb2 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Thu, 12 Sep 2019 17:05:18 +0200 Subject: [PATCH 87/94] use a thread per process to execute mosquitto loop, contributes to #248 --- lib/nodes/mqtt.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index 9cee077d8..dc169bf01 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -30,6 +30,40 @@ using namespace villas::utils; +// Each process has a list of clients for which a thread invokes the mosquitto loop +static struct vlist clients; +static pthread_t thread; + +static void * mosquitto_loop_thread(void *ctx) +{ + int ret; + while(true){ + for (unsigned i = 0; i < vlist_length(&clients); i++) { + struct node *c = (struct node *) vlist_at(&clients, i); + struct mqtt *m = (struct mqtt *) c->_vd; + + // execute mosquitto loop for this client + ret = mosquitto_loop(m->client, 0, 1); + if(ret){ + warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(c), mosquitto_strerror(ret)); + ret = mosquitto_reconnect(m->client); + if(ret != MOSQ_ERR_SUCCESS){ + error("MQTT: reconnection to broker failed for node %s: %s", node_name(c), mosquitto_strerror(ret)); + } + else{ + warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(c), mosquitto_strerror(ret)); + } + ret = mosquitto_loop(m->client, -1, 1); + if(ret != MOSQ_ERR_SUCCESS){ + error("MQTT: persisting connection error for node %s: %s", node_name(c), mosquitto_strerror(ret)); + } + } + } // for loop + } // while(1) + + return nullptr; +} + static void mqtt_log_cb(struct mosquitto *mosq, void *userdata, int level, const char *str) { switch (level) { @@ -331,9 +365,9 @@ int mqtt_start(struct node *n) if (ret) goto mosquitto_error; - ret = mosquitto_loop_start(m->client); - if (ret) - goto mosquitto_error; + // add client to global list of MQTT clients + // so that thread can call mosquitto loop for this client + vlist_push(&clients, n); return 0; @@ -352,9 +386,9 @@ int mqtt_stop(struct node *n) if (ret) goto mosquitto_error; - ret = mosquitto_loop_stop(m->client, 0); - if (ret) - goto mosquitto_error; + // unregister client from global MQTT client list + // so that mosquitto loop is no longer invoked for this client + vlist_remove_all(&clients, n); ret = io_destroy(&m->io); if (ret) @@ -372,10 +406,21 @@ int mqtt_type_start(villas::node::SuperNode *sn) { int ret; + ret = vlist_init(&clients); + if (ret) { + return ret; + } + ret = mosquitto_lib_init(); if (ret) goto mosquitto_error; + // start thread here to run mosquitto loop for registered clients + ret = pthread_create(&thread, nullptr, mosquitto_loop_thread, nullptr); + if (ret) { + return ret; + } + return 0; mosquitto_error: @@ -388,10 +433,26 @@ int mqtt_type_stop() { int ret; + // stop thread here that executes mosquitto loop + ret = pthread_cancel(thread); + if (ret) + return ret; + + ret = pthread_join(thread, nullptr); + if (ret) { + return ret; + } + ret = mosquitto_lib_cleanup(); if (ret) goto mosquitto_error; + // when this is called the list of clients should be empty + if (vlist_length(&clients) > 0) { + error("List of MQTT clients contains elements at time of destruction. Call node_stop for each MQTT node before stopping node type!"); + } + vlist_destroy(&clients, nullptr, false); + return 0; mosquitto_error: From 3624cb9fcac842fc0c8045510fdc6a2d8c455124 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Fri, 13 Sep 2019 09:02:40 +0200 Subject: [PATCH 88/94] renaming variable to improve readability --- lib/nodes/mqtt.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index dc169bf01..96f87b37a 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -39,23 +39,23 @@ static void * mosquitto_loop_thread(void *ctx) int ret; while(true){ for (unsigned i = 0; i < vlist_length(&clients); i++) { - struct node *c = (struct node *) vlist_at(&clients, i); - struct mqtt *m = (struct mqtt *) c->_vd; + struct node *node = (struct node *) vlist_at(&clients, i); + struct mqtt *m = (struct mqtt *) node->_vd; // execute mosquitto loop for this client ret = mosquitto_loop(m->client, 0, 1); if(ret){ - warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(c), mosquitto_strerror(ret)); + warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(node), mosquitto_strerror(ret)); ret = mosquitto_reconnect(m->client); if(ret != MOSQ_ERR_SUCCESS){ - error("MQTT: reconnection to broker failed for node %s: %s", node_name(c), mosquitto_strerror(ret)); + error("MQTT: reconnection to broker failed for node %s: %s", node_name(node), mosquitto_strerror(ret)); } else{ - warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(c), mosquitto_strerror(ret)); + warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(node), mosquitto_strerror(ret)); } ret = mosquitto_loop(m->client, -1, 1); if(ret != MOSQ_ERR_SUCCESS){ - error("MQTT: persisting connection error for node %s: %s", node_name(c), mosquitto_strerror(ret)); + error("MQTT: persisting connection error for node %s: %s", node_name(node), mosquitto_strerror(ret)); } } } // for loop From e52d2f77eeab1897bf8235a03d12ac5913f9d1fb Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Fri, 13 Sep 2019 09:56:50 +0200 Subject: [PATCH 89/94] improve unthreaded implementation of MQTT node type - set cancel type of MQTT communication management thread to asynchronous - fix removing node from list in mqtt_stop - add a debug output upon invocation of pthread cancel in mqtt_type_stop - contributes to #248 --- lib/nodes/mqtt.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index 96f87b37a..0770f21a5 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -37,6 +37,13 @@ static pthread_t thread; static void * mosquitto_loop_thread(void *ctx) { int ret; + // set the cancel type of this thread to async + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); + if (ret != 0) { + error("Unable to set cancel type of MQTT communication thread to asynchronous."); + return nullptr; + } + while(true){ for (unsigned i = 0; i < vlist_length(&clients); i++) { struct node *node = (struct node *) vlist_at(&clients, i); @@ -382,14 +389,15 @@ int mqtt_stop(struct node *n) int ret; struct mqtt *m = (struct mqtt *) n->_vd; + // unregister client from global MQTT client list + // so that mosquitto loop is no longer invoked for this client + // important to do that before disconnecting from broker, otherwise, mosquitto thread will attempt to reconnect + vlist_remove(&clients, vlist_index(&clients, n)); + ret = mosquitto_disconnect(m->client); if (ret) goto mosquitto_error; - // unregister client from global MQTT client list - // so that mosquitto loop is no longer invoked for this client - vlist_remove_all(&clients, n); - ret = io_destroy(&m->io); if (ret) return ret; @@ -437,6 +445,7 @@ int mqtt_type_stop() ret = pthread_cancel(thread); if (ret) return ret; + debug( 3, "Called pthread_cancel() on MQTT communication management thread."); ret = pthread_join(thread, nullptr); if (ret) { From ff8151bee0e01678a76f40f635896e67bf75d81b Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Fri, 13 Sep 2019 10:15:03 +0200 Subject: [PATCH 90/94] remove files of mqtt_unthreaded node type since this is implemented in mqtt type now --- include/villas/nodes/mqtt_unthreaded.hpp | 49 ---- lib/nodes/CMakeLists.txt | 2 +- lib/nodes/mqtt_unthreaded.cpp | 339 ----------------------- 3 files changed, 1 insertion(+), 389 deletions(-) delete mode 100644 include/villas/nodes/mqtt_unthreaded.hpp delete mode 100644 lib/nodes/mqtt_unthreaded.cpp diff --git a/include/villas/nodes/mqtt_unthreaded.hpp b/include/villas/nodes/mqtt_unthreaded.hpp deleted file mode 100644 index 4b9a37af1..000000000 --- a/include/villas/nodes/mqtt_unthreaded.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/** Node type: mqtt_unthreaded - * - * @file - * @author Steffen Vogel - * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASnode - * - * 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 - * 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 . - *********************************************************************************/ - -/** - * @addtogroup mqtt_unthreaded mqtt unthreaded node type - * @ingroup node - * @{ - */ - -#pragma once - -#include - -/** @see node_type::open */ -int mqtt_unthreaded_start(struct node *n); - -/** @see node_type::close */ -int mqtt_unthreaded_stop(struct node *n); - -/** @see node_type::read */ -int mqtt_unthreaded_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release); - -/** @see node_type::write */ -int mqtt_unthreaded_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release); - -/** perform MQTT network operations */ -int mqtt_unthreaded_loop(struct node *n); - -/** @} */ diff --git a/lib/nodes/CMakeLists.txt b/lib/nodes/CMakeLists.txt index db8759a8d..516743f66 100644 --- a/lib/nodes/CMakeLists.txt +++ b/lib/nodes/CMakeLists.txt @@ -126,7 +126,7 @@ endif() # Enable MQTT support if(WITH_NODE_MQTT) - list(APPEND NODE_SRC mqtt.cpp mqtt_unthreaded.cpp) + list(APPEND NODE_SRC mqtt.cpp) list(APPEND INCLUDE_DIRS ${MOSQUITTO_INCLUDE_DIRS}) list(APPEND LIBRARIES ${MOSQUITTO_LIBRARIES}) endif() diff --git a/lib/nodes/mqtt_unthreaded.cpp b/lib/nodes/mqtt_unthreaded.cpp deleted file mode 100644 index dafaefabb..000000000 --- a/lib/nodes/mqtt_unthreaded.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/** Node type: mqtt_unthreaded - * - * @author Steffen Vogel - * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASnode - * - * 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 - * 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 . - *********************************************************************************/ - -#include -#include - -#include -#include -#include -#include - -static void mqtt_unthreaded_log_cb(struct mosquitto *mosq, void *userdata, int level, const char *str) -{ - switch (level) { - case MOSQ_LOG_NONE: - case MOSQ_LOG_INFO: - case MOSQ_LOG_NOTICE: - info("MQTT: %s", str); - break; - - case MOSQ_LOG_WARNING: - warning("MQTT: %s", str); - break; - - case MOSQ_LOG_ERR: - error("MQTT: %s", str); - break; - - case MOSQ_LOG_DEBUG: - debug(5, "MQTT: %s", str); - break; - } -} - - -static void mqtt_unthreaded_connect_cb(struct mosquitto *mosq, void *userdata, int result) -{ - struct node *n = (struct node *) userdata; - struct mqtt *m = (struct mqtt *) n->_vd; - - int ret; - - info("MQTT: Node %s connected to broker %s", node_name(n), m->host); - - if (m->subscribe) { - ret = mosquitto_subscribe(m->client, nullptr, m->subscribe, m->qos); - if (ret) - warning("MQTT: failed to subscribe to topic '%s' for node %s: %s", m->subscribe, node_name(n), mosquitto_strerror(ret)); - } - else - warning("MQTT: no subscribe for node %s as no subscribe topic is given", node_name(n)); - - mqtt_unthreaded_loop(n); -} - -static void mqtt_unthreaded_message_cb(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg) -{ - int ret; - struct node *n = (struct node *) userdata; - struct mqtt *m = (struct mqtt *) n->_vd; - struct sample *smps[n->in.vectorize]; - - debug(5, "MQTT: Node %s received a message of %d bytes from broker %s", node_name(n), msg->payloadlen, m->host); - - ret = sample_alloc_many(&m->pool, smps, n->in.vectorize); - if (ret <= 0) { - warning("Pool underrun in subscriber of %s", node_name(n)); - return; - } - - ret = io_sscan(&m->io, (char *) msg->payload, msg->payloadlen, nullptr, smps, n->in.vectorize); - if (ret < 0) { - warning("MQTT: Node %s received an invalid message", node_name(n)); - warning(" Payload: %s", (char *) msg->payload); - return; - } - if (ret == 0) { - debug(4, "MQTT: skip empty message for node %s", node_name(n)); - sample_decref_many(smps, n->in.vectorize); - return; - } - - queue_signalled_push_many(&m->queue, (void **) smps, n->in.vectorize); - mqtt_unthreaded_loop(n); -} - -static void mqtt_unthreaded_disconnect_cb(struct mosquitto *mosq, void *userdata, int result) -{ - struct node *n = (struct node *) userdata; - struct mqtt *m = (struct mqtt *) n->_vd; - - info("MQTT: Node %s disconnected from broker %s", node_name(n), m->host); -} - - -static void mqtt_unthreaded_subscribe_cb(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos) -{ - struct node *n = (struct node *) userdata; - struct mqtt *m = (struct mqtt *) n->_vd; - - info("MQTT: Node %s subscribed to broker %s", node_name(n), m->host); - n->state=STATE_STARTED; -} - -int mqtt_unthreaded_check(struct node *n) -{ - int ret; - struct mqtt *m = (struct mqtt *) n->_vd; - - ret = mosquitto_sub_topic_check(m->subscribe); - if (ret != MOSQ_ERR_SUCCESS) - error("Invalid subscribe topic: '%s' for node %s: %s", m->subscribe, node_name(n), mosquitto_strerror(ret)); - - ret = mosquitto_pub_topic_check(m->publish); - if (ret != MOSQ_ERR_SUCCESS) - error("Invalid publish topic: '%s' for node %s: %s", m->publish, node_name(n), mosquitto_strerror(ret)); - - return 0; -} - - - -int mqtt_unthreaded_start(struct node *n) -{ - int ret; - struct mqtt *m = (struct mqtt *) n->_vd; - - m->client = mosquitto_new(n->name, 0, (void *) n); - if (!m->client) - return -1; - - if (m->username && m->password) { - ret = mosquitto_username_pw_set(m->client, m->username, m->password); - if (ret) - goto mosquitto_error; - } - - if (m->ssl.enabled) { - ret = mosquitto_tls_set(m->client, m->ssl.cafile, m->ssl.capath, m->ssl.certfile, m->ssl.keyfile, nullptr); - if (ret) - goto mosquitto_error; - - ret = mosquitto_tls_insecure_set(m->client, m->ssl.insecure); - if (ret) - goto mosquitto_error; - } - - mosquitto_log_callback_set(m->client, mqtt_unthreaded_log_cb); - mosquitto_connect_callback_set(m->client, mqtt_unthreaded_connect_cb); - mosquitto_disconnect_callback_set(m->client, mqtt_unthreaded_disconnect_cb); - mosquitto_message_callback_set(m->client, mqtt_unthreaded_message_cb); - mosquitto_subscribe_callback_set(m->client, mqtt_unthreaded_subscribe_cb); - - ret = io_init(&m->io, m->format, &n->in.signals, SAMPLE_HAS_ALL & ~SAMPLE_HAS_OFFSET); - if (ret) - return ret; - - ret = io_check(&m->io); - if (ret) - return ret; - - ret = pool_init(&m->pool, 1024, SAMPLE_LENGTH(vlist_length(&n->in.signals)), &memory_hugepage); - if (ret) - return ret; - - ret = queue_signalled_init(&m->queue, 1024, &memory_hugepage, 0); - if (ret) - return ret; - - ret = mosquitto_connect(m->client, m->host, m->port, m->keepalive); - if (ret) - goto mosquitto_error; - - //The following while loop exists upon completion of subscibe procedure - while(n->state == STATE_PREPARED){ - mqtt_unthreaded_loop(n); - } - - return 0; - -mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); - - return ret; -} - -int mqtt_unthreaded_stop(struct node *n) -{ - int ret; - struct mqtt *m = (struct mqtt *) n->_vd; - - ret = mosquitto_disconnect(m->client); - if (ret) - goto mosquitto_error; - - ret = io_destroy(&m->io); - if (ret) - return ret; - - return 0; - -mosquitto_error: - warning("MQTT: %s", mosquitto_strerror(ret)); - - return ret; -} - -int mqtt_unthreaded_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release) -{ - int pulled=0; - mqtt_unthreaded_loop(n); - - if(cnt > 0){ - struct mqtt *m = (struct mqtt *) n->_vd; - struct sample *smpt[cnt]; - pulled = queue_signalled_pull_many(&m->queue, (void **) smpt, cnt); - - sample_copy_many(smps, smpt, pulled); - sample_decref_many(smpt, pulled); - } - return pulled; -} - -int mqtt_unthreaded_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *release) -{ - int ret; - struct mqtt *m = (struct mqtt *) n->_vd; - - size_t wbytes; - - char data[1500]; - - ret = io_sprint(&m->io, data, sizeof(data), &wbytes, smps, cnt); - if (ret < 0) - return ret; - - if (m->publish) { - ret = mosquitto_publish(m->client, nullptr /* mid */, m->publish, wbytes, data, m->qos, m->retain); - if (ret != MOSQ_ERR_SUCCESS) { - warning("MQTT: publish failed for node %s: %s", node_name(n), mosquitto_strerror(ret)); - return -abs(ret); - } - } - else - warning("MQTT: no publish for node %s possible because no publish topic is given", node_name(n)); - - mqtt_unthreaded_loop(n); - - return cnt; -} - -int mqtt_unthreaded_loop(struct node *n){ - - int ret; - struct mqtt *m = (struct mqtt *) n->_vd; - - //Carry out network operations in a synchronous way. - ret = mosquitto_loop(m->client, 0, 1); - if(ret){ - warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(n), mosquitto_strerror(ret)); - ret = mosquitto_reconnect(m->client); - if(ret != MOSQ_ERR_SUCCESS){ - error("MQTT: reconnection to broker failed for node %s: %s", node_name(n), mosquitto_strerror(ret)); - } - else{ - warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(n), mosquitto_strerror(ret)); - } - ret = mosquitto_loop(m->client, -1, 1); - if(ret != MOSQ_ERR_SUCCESS){ - error("MQTT: persisting connection error for node %s: %s", node_name(n), mosquitto_strerror(ret)); - } - } - - return 0; -} - -int mqtt_unthreaded_poll_fds(struct node *n, int fds[]) -{ - struct mqtt *m = (struct mqtt *) n->_vd; - - fds[0] = queue_signalled_fd(&m->queue); - - return 1; -} - -static struct plugin p; - -__attribute__((constructor(110))) -static void register_plugin() { - if (plugins.state == STATE_DESTROYED) - vlist_init(&plugins); - - p.name = "mqtt_unthreaded"; - p.description = "Message Queuing Telemetry Transport (libmosquitto), unthreaded variant"; - p.type = PLUGIN_TYPE_NODE; - p.node.instances.state = STATE_DESTROYED; - p.node.vectorize = 0; - p.node.size = sizeof(struct mqtt); - p.node.type.start = mqtt_type_start; - p.node.type.stop = mqtt_type_stop; - p.node.destroy = mqtt_destroy; - p.node.parse = mqtt_parse; - p.node.check = mqtt_unthreaded_check; - p.node.print = mqtt_print; - p.node.start = mqtt_unthreaded_start; - p.node.stop = mqtt_unthreaded_stop; - p.node.read = mqtt_unthreaded_read; - p.node.write = mqtt_unthreaded_write; - p.node.reverse = mqtt_reverse; - p.node.poll_fds = mqtt_unthreaded_poll_fds; - - vlist_init(&p.node.instances); - vlist_push(&plugins, &p); -} - -__attribute__((destructor(110))) -static void deregister_plugin() { - if (plugins.state != STATE_DESTROYED) - vlist_remove_all(&plugins, &p); -} From 69f76420ee24c985eb20aad4f9fe981a036ee8c1 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Mon, 16 Sep 2019 09:48:22 +0200 Subject: [PATCH 91/94] fix indentation --- lib/nodes/mqtt.cpp | 104 ++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index 0770f21a5..b88cab9d7 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -36,39 +36,39 @@ static pthread_t thread; static void * mosquitto_loop_thread(void *ctx) { - int ret; - // set the cancel type of this thread to async - ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); - if (ret != 0) { - error("Unable to set cancel type of MQTT communication thread to asynchronous."); - return nullptr; - } + int ret; + // set the cancel type of this thread to async + ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); + if (ret != 0) { + error("Unable to set cancel type of MQTT communication thread to asynchronous."); + return nullptr; + } - while(true){ - for (unsigned i = 0; i < vlist_length(&clients); i++) { - struct node *node = (struct node *) vlist_at(&clients, i); - struct mqtt *m = (struct mqtt *) node->_vd; + while(true){ + for (unsigned i = 0; i < vlist_length(&clients); i++) { + struct node *node = (struct node *) vlist_at(&clients, i); + struct mqtt *m = (struct mqtt *) node->_vd; - // execute mosquitto loop for this client - ret = mosquitto_loop(m->client, 0, 1); - if(ret){ - warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(node), mosquitto_strerror(ret)); - ret = mosquitto_reconnect(m->client); - if(ret != MOSQ_ERR_SUCCESS){ - error("MQTT: reconnection to broker failed for node %s: %s", node_name(node), mosquitto_strerror(ret)); - } - else{ - warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(node), mosquitto_strerror(ret)); - } - ret = mosquitto_loop(m->client, -1, 1); - if(ret != MOSQ_ERR_SUCCESS){ - error("MQTT: persisting connection error for node %s: %s", node_name(node), mosquitto_strerror(ret)); - } - } - } // for loop - } // while(1) + // execute mosquitto loop for this client + ret = mosquitto_loop(m->client, 0, 1); + if(ret){ + warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(node), mosquitto_strerror(ret)); + ret = mosquitto_reconnect(m->client); + if(ret != MOSQ_ERR_SUCCESS){ + error("MQTT: reconnection to broker failed for node %s: %s", node_name(node), mosquitto_strerror(ret)); + } + else{ + warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(node), mosquitto_strerror(ret)); + } + ret = mosquitto_loop(m->client, -1, 1); + if(ret != MOSQ_ERR_SUCCESS){ + error("MQTT: persisting connection error for node %s: %s", node_name(node), mosquitto_strerror(ret)); + } + } + } // for loop + } // while(1) - return nullptr; + return nullptr; } static void mqtt_log_cb(struct mosquitto *mosq, void *userdata, int level, const char *str) @@ -374,7 +374,7 @@ int mqtt_start(struct node *n) // add client to global list of MQTT clients // so that thread can call mosquitto loop for this client - vlist_push(&clients, n); + vlist_push(&clients, n); return 0; @@ -389,10 +389,10 @@ int mqtt_stop(struct node *n) int ret; struct mqtt *m = (struct mqtt *) n->_vd; - // unregister client from global MQTT client list - // so that mosquitto loop is no longer invoked for this client - // important to do that before disconnecting from broker, otherwise, mosquitto thread will attempt to reconnect - vlist_remove(&clients, vlist_index(&clients, n)); + // unregister client from global MQTT client list + // so that mosquitto loop is no longer invoked for this client + // important to do that before disconnecting from broker, otherwise, mosquitto thread will attempt to reconnect + vlist_remove(&clients, vlist_index(&clients, n)); ret = mosquitto_disconnect(m->client); if (ret) @@ -414,20 +414,20 @@ int mqtt_type_start(villas::node::SuperNode *sn) { int ret; - ret = vlist_init(&clients); - if (ret) { - return ret; - } + ret = vlist_init(&clients); + if (ret) { + return ret; + } ret = mosquitto_lib_init(); if (ret) goto mosquitto_error; // start thread here to run mosquitto loop for registered clients - ret = pthread_create(&thread, nullptr, mosquitto_loop_thread, nullptr); - if (ret) { - return ret; - } + ret = pthread_create(&thread, nullptr, mosquitto_loop_thread, nullptr); + if (ret) { + return ret; + } return 0; @@ -442,15 +442,15 @@ int mqtt_type_stop() int ret; // stop thread here that executes mosquitto loop - ret = pthread_cancel(thread); - if (ret) - return ret; - debug( 3, "Called pthread_cancel() on MQTT communication management thread."); + ret = pthread_cancel(thread); + if (ret) + return ret; + debug( 3, "Called pthread_cancel() on MQTT communication management thread."); - ret = pthread_join(thread, nullptr); - if (ret) { - return ret; - } + ret = pthread_join(thread, nullptr); + if (ret) { + return ret; + } ret = mosquitto_lib_cleanup(); if (ret) @@ -460,7 +460,7 @@ int mqtt_type_stop() if (vlist_length(&clients) > 0) { error("List of MQTT clients contains elements at time of destruction. Call node_stop for each MQTT node before stopping node type!"); } - vlist_destroy(&clients, nullptr, false); + vlist_destroy(&clients, nullptr, false); return 0; From 31623673a4cd31b10367278c2c058f61680133bd Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 3 Oct 2019 11:28:19 +0200 Subject: [PATCH 92/94] minor code-style fixes --- lib/nodes/mqtt.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/nodes/mqtt.cpp b/lib/nodes/mqtt.cpp index b88cab9d7..1e69d7ab4 100644 --- a/lib/nodes/mqtt.cpp +++ b/lib/nodes/mqtt.cpp @@ -37,36 +37,36 @@ static pthread_t thread; static void * mosquitto_loop_thread(void *ctx) { int ret; - // set the cancel type of this thread to async + + // Set the cancel type of this thread to async ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); if (ret != 0) { error("Unable to set cancel type of MQTT communication thread to asynchronous."); return nullptr; } - while(true){ + while (true) { for (unsigned i = 0; i < vlist_length(&clients); i++) { struct node *node = (struct node *) vlist_at(&clients, i); struct mqtt *m = (struct mqtt *) node->_vd; - // execute mosquitto loop for this client + // Execute mosquitto loop for this client ret = mosquitto_loop(m->client, 0, 1); - if(ret){ + if (ret) { warning("MQTT: connection error for node %s: %s, attempting reconnect", node_name(node), mosquitto_strerror(ret)); + ret = mosquitto_reconnect(m->client); - if(ret != MOSQ_ERR_SUCCESS){ + if (ret != MOSQ_ERR_SUCCESS) error("MQTT: reconnection to broker failed for node %s: %s", node_name(node), mosquitto_strerror(ret)); - } - else{ + else warning("MQTT: successfully reconnected to broker for node %s: %s", node_name(node), mosquitto_strerror(ret)); - } + ret = mosquitto_loop(m->client, -1, 1); - if(ret != MOSQ_ERR_SUCCESS){ + if (ret != MOSQ_ERR_SUCCESS) error("MQTT: persisting connection error for node %s: %s", node_name(node), mosquitto_strerror(ret)); - } } - } // for loop - } // while(1) + } + } return nullptr; } @@ -141,6 +141,7 @@ static void mqtt_message_cb(struct mosquitto *mosq, void *userdata, const struct warning(" Payload: %s", (char *) msg->payload); return; } + if (ret == 0) { debug(4, "MQTT: skip empty message for node %s", node_name(n)); sample_decref_many(smps, n->in.vectorize); @@ -372,7 +373,7 @@ int mqtt_start(struct node *n) if (ret) goto mosquitto_error; - // add client to global list of MQTT clients + // Add client to global list of MQTT clients // so that thread can call mosquitto loop for this client vlist_push(&clients, n); @@ -389,7 +390,7 @@ int mqtt_stop(struct node *n) int ret; struct mqtt *m = (struct mqtt *) n->_vd; - // unregister client from global MQTT client list + // Unregister client from global MQTT client list // so that mosquitto loop is no longer invoked for this client // important to do that before disconnecting from broker, otherwise, mosquitto thread will attempt to reconnect vlist_remove(&clients, vlist_index(&clients, n)); @@ -423,7 +424,7 @@ int mqtt_type_start(villas::node::SuperNode *sn) if (ret) goto mosquitto_error; - // start thread here to run mosquitto loop for registered clients + // Start thread here to run mosquitto loop for registered clients ret = pthread_create(&thread, nullptr, mosquitto_loop_thread, nullptr); if (ret) { return ret; @@ -441,7 +442,7 @@ int mqtt_type_stop() { int ret; - // stop thread here that executes mosquitto loop + // Stop thread here that executes mosquitto loop ret = pthread_cancel(thread); if (ret) return ret; @@ -456,7 +457,7 @@ int mqtt_type_stop() if (ret) goto mosquitto_error; - // when this is called the list of clients should be empty + // When this is called the list of clients should be empty if (vlist_length(&clients) > 0) { error("List of MQTT clients contains elements at time of destruction. Call node_stop for each MQTT node before stopping node type!"); } From c72fd1718dfa952e2a292c4033c2d7c024b67261 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 3 Oct 2019 11:34:59 +0200 Subject: [PATCH 93/94] fix invalid variable name --- lib/formats/msg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/formats/msg.cpp b/lib/formats/msg.cpp index 4568440af..9fdcfc456 100644 --- a/lib/formats/msg.cpp +++ b/lib/formats/msg.cpp @@ -110,8 +110,8 @@ int msg_from_sample(struct msg *msg_in, struct sample *smp, struct vlist *signal { msg_in->type = MSG_TYPE_DATA; msg_in->version = MSG_VERSION; - msg_in->rsvd1 = 0; - msg_in->resv2 = 0; + msg_in->reserved1 = 0; + msg_in->reserved2 = 0; msg_in->length = (uint16_t) smp->length; msg_in->sequence = (uint32_t) smp->sequence; msg_in->ts.sec = smp->ts.origin.tv_sec; From df29094a14de8c42e597889256571acacc7b77e3 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 3 Oct 2019 11:44:29 +0200 Subject: [PATCH 94/94] fix merge of pps_ts hook --- lib/hooks/pps_ts.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/hooks/pps_ts.cpp b/lib/hooks/pps_ts.cpp index fa5ea693c..0cbc04b4c 100644 --- a/lib/hooks/pps_ts.cpp +++ b/lib/hooks/pps_ts.cpp @@ -63,7 +63,7 @@ public: int ret; json_error_t err; - assert(state != STATE_STARTED); + assert(state != State::STARTED); ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s?: f }", "signal_index", &idx, @@ -74,12 +74,12 @@ public: info("parsed config thresh=%f signal_index=%d", thresh, idx); - state = STATE_PARSED; + state = State::PARSED; } - virtual int process(sample *smp) + virtual villas::node::Hook::Reason process(sample *smp) { - assert(state == STATE_STARTED); + assert(state == State::STARTED); /* Get value of PPS signal */ float value = smp->data[idx].f; // TODO check if it is really float @@ -109,7 +109,7 @@ public: lastValue = value; if (edgeCounter < 2) - return HOOK_SKIP_SAMPLE; + return Hook::Reason::SKIP_SAMPLE; else if (edgeCounter == 2 && isEdge) realTime.tv_nsec = 0; else @@ -122,9 +122,9 @@ public: /* Update timestamp */ smp->ts.origin = realTime; - smp->flags |= SAMPLE_HAS_TS_ORIGIN; + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; - return HOOK_OK; + return Hook::Reason::OK; } }; @@ -132,7 +132,7 @@ public: static HookPlugin p( "pps_ts", "Timestamp samples based GPS PPS signal", - HOOK_NODE_READ | HOOK_NODE_WRITE | HOOK_PATH, + (int) Hook::Flags::NODE_READ | (int) Hook::Flags::NODE_WRITE | (int) Hook::Flags::PATH, 99 );