diff --git a/src/villas-convert.cpp b/src/villas-convert.cpp index eb771ea09..a9a7abe33 100644 --- a/src/villas-convert.cpp +++ b/src/villas-convert.cpp @@ -52,100 +52,112 @@ static void usage() int main(int argc, char *argv[]) { - int ret; - const char *input_format = "villas.human"; - const char *output_format = "villas.human"; - const char *dtypes = "64f"; + Logger logger = logging.get("test-rtt"); - /* Parse optional command line arguments */ - int c; - while ((c = getopt(argc, argv, "Vhd:i:o:t:")) != -1) { - switch (c) { - case 'V': - print_version(); - exit(EXIT_SUCCESS); + try { + int ret; + const char *input_format = "villas.human"; + const char *output_format = "villas.human"; + const char *dtypes = "64f"; - case 'i': - input_format = optarg; - break; + /* Parse optional command line arguments */ + int c; + while ((c = getopt(argc, argv, "Vhd:i:o:t:")) != -1) { + switch (c) { + case 'V': + print_version(); + exit(EXIT_SUCCESS); - case 'o': - output_format = optarg; - break; + case 'i': + input_format = optarg; + break; - case 't': - dtypes = optarg; - break; + case 'o': + output_format = optarg; + break; - case 'd': - logging.setLevel(optarg); - break; + case 't': + dtypes = optarg; + break; - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + case 'd': + logging.setLevel(optarg); + break; + + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + } } + + if (argc != optind) { + 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 }, + }; + + 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); + + ret = io_init2(dirs[i].io, ft, dtypes, SAMPLE_HAS_ALL); + if (ret) + throw RuntimeError("Failed to initialize IO: {}", dirs[i].name); + + ret = io_check(dirs[i].io); + if (ret) + throw RuntimeError("Failed to validate IO configuration"); + + ret = io_open(dirs[i].io, nullptr); + if (ret) + throw RuntimeError("Failed to open IO"); + } + + struct sample *smp = sample_alloc_mem(DEFAULT_SAMPLE_LENGTH); + + for (;;) { + ret = io_scan(&input, &smp, 1); + if (ret == 0) + continue; + if (ret < 0) + break; + + io_print(&output, &smp, 1); + } + + for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) { + ret = io_close(dirs[i].io); + if (ret) + throw RuntimeError("Failed to close 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()); - if (argc != optind) { - usage(); - exit(EXIT_FAILURE); + return -1; } - - struct format_type *ft; - struct io input = { .state = STATE_DESTROYED }; - struct io output = { .state = STATE_DESTROYED }; - - struct { - const char *name; - struct io *io; - } dirs[] = { - { input_format, &input }, - { output_format, &output }, - }; - - 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); - - ret = io_init2(dirs[i].io, ft, dtypes, SAMPLE_HAS_ALL); - if (ret) - throw RuntimeError("Failed to initialize IO: {}", dirs[i].name); - - ret = io_check(dirs[i].io); - if (ret) - throw RuntimeError("Failed to validate IO configuration"); - - ret = io_open(dirs[i].io, nullptr); - if (ret) - throw RuntimeError("Failed to open IO"); - } - - struct sample *smp = sample_alloc_mem(DEFAULT_SAMPLE_LENGTH); - - for (;;) { - ret = io_scan(&input, &smp, 1); - if (ret == 0) - continue; - if (ret < 0) - break; - - io_print(&output, &smp, 1); - } - - for (unsigned i = 0; i < ARRAY_LEN(dirs); i++) { - ret = io_close(dirs[i].io); - if (ret) - throw RuntimeError("Failed to close IO"); - - ret = io_destroy(dirs[i].io); - if (ret) - throw RuntimeError("Failed to destroy IO"); - } - - return 0; } /** @} */ diff --git a/src/villas-hook.cpp b/src/villas-hook.cpp index b75f5d4bb..793d32ef7 100644 --- a/src/villas-hook.cpp +++ b/src/villas-hook.cpp @@ -99,8 +99,11 @@ int main(int argc, char *argv[]) Logger logger = logging.get("hook"); try { - struct pool p = { .state = STATE_DESTROYED }; - struct io io = { .state = STATE_DESTROYED }; + struct pool p; + struct io io; + + p.state = STATE_DESTROYED; + io.state = STATE_DESTROYED; /* Default values */ cnt = 1; diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index a4e9a66c9..f69a9815c 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -251,210 +251,218 @@ leave2: stop = true; int main(int argc, char *argv[]) { - int ret, timeout = 0; - bool reverse = false; - const char *format = "villas.human"; - const char *dtypes = "64f"; - - struct node *node; - static struct io io = { .state = STATE_DESTROYED }; - - SuperNode sn; /**< The global configuration */ Logger logger = logging.get("pipe"); - json_t *cfg_cli = json_object(); + try { + int ret, timeout = 0; + bool reverse = false; + const char *format = "villas.human"; + const char *dtypes = "64f"; - bool enable_send = true, enable_recv = true; - int limit_send = -1, limit_recv = -1; + struct node *node; + static struct io io = { .state = STATE_DESTROYED }; - /* Parse optional command line arguments */ - int c; - char *endptr; - while ((c = getopt(argc, argv, "Vhxrsd:l:L:T:f:t:o:")) != -1) { - switch (c) { - case 'V': - print_version(); - exit(EXIT_SUCCESS); + SuperNode sn; /**< The global configuration */ - case 'f': - format = optarg; - break; + json_t *cfg_cli = json_object(); - case 't': - dtypes = optarg; - break; + bool enable_send = true, enable_recv = true; + int limit_send = -1, limit_recv = -1; - case 'x': - reverse = true; - break; + /* Parse optional command line arguments */ + int c; + char *endptr; + while ((c = getopt(argc, argv, "Vhxrsd:l:L:T:f:t:o:")) != -1) { + switch (c) { + case 'V': + print_version(); + exit(EXIT_SUCCESS); - case 's': - enable_recv = false; // send only - break; + case 'f': + format = optarg; + break; - case 'r': - enable_send = false; // receive only - break; + case 't': + dtypes = optarg; + break; - case 'l': - limit_recv = strtoul(optarg, &endptr, 10); - goto check; + case 'x': + reverse = true; + break; - case 'L': - limit_send = strtoul(optarg, &endptr, 10); - goto check; + case 's': + enable_recv = false; // send only + break; - case 'T': - timeout = strtoul(optarg, &endptr, 10); - goto check; + case 'r': + enable_send = false; // receive only + break; - case 'o': - ret = json_object_extend_str(cfg_cli, optarg); - if (ret) - throw RuntimeError("Invalid option: {}", optarg); - break; + case 'l': + limit_recv = strtoul(optarg, &endptr, 10); + goto check; - case 'd': - logging.setLevel(optarg); - break; + case 'L': + limit_send = strtoul(optarg, &endptr, 10); + goto check; - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + case 'T': + timeout = strtoul(optarg, &endptr, 10); + goto check; + + case 'o': + ret = json_object_extend_str(cfg_cli, optarg); + if (ret) + throw RuntimeError("Invalid option: {}", optarg); + break; + + case 'd': + logging.setLevel(optarg); + break; + + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + } + + continue; + +check: if (optarg == endptr) + throw RuntimeError("Failed to parse parse option argument '-{} {}'", c, optarg); } - continue; + if (argc != optind + 2) { + usage(); + exit(EXIT_FAILURE); + } -check: if (optarg == endptr) - throw RuntimeError("Failed to parse parse option argument '-{} {}'", c, optarg); - } + logger->info("Logging level: {}", logging.getLevelName()); - if (argc != optind + 2) { - usage(); - exit(EXIT_FAILURE); - } + char *uri = argv[optind]; + char *nodestr = argv[optind+1]; + struct format_type *ft; - logger->info("Logging level: {}", logging.getLevelName()); + ret = memory_init(0); + if (ret) + throw RuntimeError("Failed to intialize memory"); - char *uri = argv[optind]; - char *nodestr = argv[optind+1]; - struct format_type *ft; + ret = utils::signals_init(quit); + if (ret) + throw RuntimeError("Failed to initialize signals"); - ret = memory_init(0); - if (ret) - throw RuntimeError("Failed to intialize memory"); + if (uri) + sn.parse(uri); + else + logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to initialize signals"); + ft = format_type_lookup(format); + if (!ft) + throw RuntimeError("Invalid format: {}", format); - if (uri) - sn.parse(uri); - else - logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); + ret = io_init2(&io, ft, dtypes, SAMPLE_HAS_ALL); + if (ret) + throw RuntimeError("Failed to initialize IO"); - ft = format_type_lookup(format); - if (!ft) - throw RuntimeError("Invalid format: {}", format); + ret = io_check(&io); + if (ret) + throw RuntimeError("Failed to validate IO configuration"); - ret = io_init2(&io, ft, dtypes, SAMPLE_HAS_ALL); - if (ret) - throw RuntimeError("Failed to initialize IO"); + ret = io_open(&io, nullptr); + if (ret) + throw RuntimeError("Failed to open IO"); - ret = io_check(&io); - if (ret) - throw RuntimeError("Failed to validate IO configuration"); - - ret = io_open(&io, nullptr); - if (ret) - throw RuntimeError("Failed to open IO"); - - node = sn.getNode(nodestr); - if (!node) - throw RuntimeError("Node {} does not exist!", nodestr); + node = sn.getNode(nodestr); + if (!node) + throw RuntimeError("Node {} does not exist!", nodestr); #ifdef WITH_NODE_WEBSOCKET - /* Only start web subsystem if villas-pipe is used with a websocket node */ - if (node_type(node)->start == websocket_start) { - Web *w = sn.getWeb(); - w->start(); - } + /* Only start web subsystem if villas-pipe is used with a websocket node */ + if (node_type(node)->start == websocket_start) { + Web *w = sn.getWeb(); + w->start(); + } #endif /* WITH_NODE_WEBSOCKET */ - if (reverse) - node_reverse(node); + if (reverse) + node_reverse(node); - ret = node_type_start(node_type(node), reinterpret_cast(&sn)); - if (ret) - throw RuntimeError("Failed to intialize node type {}: reason={}", node_type_name(node_type(node)), ret); + ret = node_type_start(node_type(node), reinterpret_cast(&sn)); + if (ret) + throw RuntimeError("Failed to intialize node type {}: reason={}", node_type_name(node_type(node)), ret); - sn.startInterfaces(); + sn.startInterfaces(); - ret = node_check(node); - if (ret) - throw RuntimeError("Invalid node configuration"); + ret = node_check(node); + if (ret) + throw RuntimeError("Invalid node configuration"); - ret = node_prepare(node); - if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); + ret = node_prepare(node); + if (ret) + throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); - ret = node_start(node); - if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); + ret = node_start(node); + 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) - }; + /* Start threads */ + Directions dirs = { + .send = Direction(node, &io, enable_send, limit_send), + .recv = Direction(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.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); + } + + 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); + } + + ret = node_stop(node); + if (ret) + throw RuntimeError("Failed to stop node {}: reason={}", node_name(node), ret); + + sn.stopInterfaces(); + + ret = node_type_stop(node->_vt); + if (ret) + throw RuntimeError("Failed to stop node type {}: reason={}", node_type_name(node->_vt), ret); + + ret = io_close(&io); + if (ret) + throw RuntimeError("Failed to close IO"); + + ret = io_destroy(&io); + if (ret) + throw RuntimeError("Failed to destroy IO"); + + logger->info(CLR_GRN("Goodbye!")); + + return 0; } + catch (std::runtime_error &e) { + logger->error("{}", e.what()); - if (dirs.send.enabled) { - dirs.send.node = node; - pthread_create(&dirs.send.thread, nullptr, send_loop, &dirs); + return -1; } - - 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); - } - - ret = node_stop(node); - if (ret) - throw RuntimeError("Failed to stop node {}: reason={}", node_name(node), ret); - - sn.stopInterfaces(); - - ret = node_type_stop(node->_vt); - if (ret) - throw RuntimeError("Failed to stop node type {}: reason={}", node_type_name(node->_vt), ret); - - ret = io_close(&io); - if (ret) - throw RuntimeError("Failed to close IO"); - - ret = io_destroy(&io); - if (ret) - throw RuntimeError("Failed to destroy IO"); - - logger->info(CLR_GRN("Goodbye!")); - - return 0; } /** @} */ diff --git a/src/villas-relay.cpp b/src/villas-relay.cpp index f52c8cd36..aeba1137e 100644 --- a/src/villas-relay.cpp +++ b/src/villas-relay.cpp @@ -44,9 +44,10 @@ static lws_context *context; /** The libwebsockets vhost. */ static lws_vhost *vhost; -auto console = villas::logging.get("console"); std::map sessions; +using Logger = villas::Logger; + /* Default options */ struct Options opts = { .loopback = false, @@ -116,7 +117,9 @@ Session::Session(Identifier sid) : identifier(sid), connects(0) { - console->info("Session created: {}", identifier); + Logger logger = villas::logging.get("console"); + + logger->info("Session created: {}", identifier); sessions[sid] = this; @@ -127,13 +130,17 @@ Session::Session(Identifier sid) : Session::~Session() { - console->info("Session destroyed: {}", identifier); + Logger logger = villas::logging.get("console"); + + logger->info("Session destroyed: {}", identifier); sessions.erase(identifier); } Session * Session::get(lws *wsi) { + Logger logger = villas::logging.get("console"); + char uri[64]; /* We use the URI to associate this connection to a session @@ -153,7 +160,7 @@ Session * Session::get(lws *wsi) return new Session(sid); } else { - console->info("Found existing session: {}", sid); + logger->info("Found existing session: {}", sid); return it->second; } @@ -190,6 +197,8 @@ Connection::Connection(lws *w) : frames_recv(0), frames_sent(0) { + Logger logger = villas::logging.get("console"); + session = Session::get(wsi); session->connections[wsi] = this; session->connects++; @@ -198,12 +207,14 @@ Connection::Connection(lws *w) : created = time(nullptr); - console->info("New connection established: session={}, remote={} ({})", session->identifier, name, ip); + logger->info("New connection established: session={}, remote={} ({})", session->identifier, name, ip); } Connection::~Connection() { - console->info("Connection closed: session={}, remote={} ({})", session->identifier, name, ip); + Logger logger = villas::logging.get("console"); + + logger->info("Connection closed: session={}, remote={} ({})", session->identifier, name, ip); session->connections.erase(wsi); @@ -245,13 +256,15 @@ void Connection::write() void Connection::read(void *in, size_t len) { + Logger logger = villas::logging.get("console"); + currentFrame->insert(currentFrame->end(), (uint8_t *) in, (uint8_t *) in + len); bytes_recv += len; if (lws_is_final_fragment(wsi)) { frames_recv++; - console->debug("Received frame, relaying to {} connections", session->connections.size() - (opts.loopback ? 0 : 1)); + logger->debug("Received frame, relaying to {} connections", session->connections.size() - (opts.loopback ? 0 : 1)); for (auto p : session->connections) { auto c = p.second; @@ -270,7 +283,7 @@ void Connection::read(void *in, size_t len) } } -static void logger(int level, const char *msg) +static void logger_cb(int level, const char *msg) { auto log = spdlog::get("lws"); @@ -296,6 +309,8 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi size_t json_len; json_t *json_sessions, *json_body; + Logger logger = villas::logging.get("console"); + unsigned char buf[LWS_PRE + 2048], *start = &buf[LWS_PRE], *end = &buf[sizeof(buf) - LWS_PRE - 1], *p = start; switch (reason) { @@ -341,7 +356,7 @@ int http_protocol_cb(lws *wsi, enum lws_callback_reasons reason, void *user, voi if (ret < 0) return ret; - console->info("Handled API request"); + logger->info("Handled API request"); //if (lws_http_transaction_completed(wsi)) return -1; @@ -405,79 +420,88 @@ static void usage() int main(int argc, char *argv[]) { - /* Initialize logging */ - spdlog::stdout_color_mt("lws"); - lws_set_log_level((1 << LLL_COUNT) - 1, logger); + Logger logger = villas::logging.get("console"); - /* Start server */ - lws_context_creation_info ctx_info = { 0 }; + try { + /* Initialize logging */ + spdlog::stdout_color_mt("lws"); + lws_set_log_level((1 << LLL_COUNT) - 1, logger_cb); - 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; + /* Start server */ + lws_context_creation_info ctx_info = { 0 }; - case 'p': - opts.port = strtoul(optarg, &endptr, 10); - goto check; + 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.protocol = strdup(optarg); - break; + case 'p': + opts.port = strtoul(optarg, &endptr, 10); + goto check; - case 'l': - opts.loopback = true; - break; + case 'P': + opts.protocol = strdup(optarg); + break; - case 'V': - villas::print_version(); - exit(EXIT_SUCCESS); + case 'l': + opts.loopback = true; + break; - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + 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); + } } - continue; - -check: if (optarg == endptr) { - console->error("Failed to parse parse option argument '-{} {}'", c, optarg); + 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()); - if (argc - optind < 0) { - usage(); - exit(EXIT_FAILURE); + return -1; } - - 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) { - console->error("WebSocket: failed to initialize server context"); - exit(EXIT_FAILURE); - } - - vhost = lws_create_vhost(context, &ctx_info); - if (vhost == nullptr) { - console->error("WebSocket: failed to initialize virtual host"); - exit(EXIT_FAILURE); - } - - for (;;) - lws_service(context, 100); - - return 0; } diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 238d6e18d..471545acc 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -186,130 +186,138 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx) int main(int argc, char *argv[]) { - int ret; - json_t *cfg; - struct node_type *nt; - struct format_type *ft; - - const char *format = "villas.human"; /** @todo hardcoded for now */ - - struct node n; - n.state = STATE_DESTROYED; - n.in.state = STATE_DESTROYED; - n.out.state = STATE_DESTROYED; - - struct io io = { .state = STATE_DESTROYED }; - struct pool q = { .state = STATE_DESTROYED }; - struct sample *t; - - q.queue.state = STATE_DESTROYED; - Logger logger = logging.get("signal"); - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to intialize signals"); + try { + int ret; + json_t *cfg; + struct node_type *nt; + struct format_type *ft; - ret = memory_init(0); - if (ret) - throw RuntimeError("Failed to initialize memory"); + char *format = (char *) "villas.human"; /** @todo hardcoded for now */ - nt = node_type_lookup("signal"); - if (!nt) - throw RuntimeError("Signal generation is not supported."); + struct node n; + struct io io; + struct pool q; + struct sample *t; - ret = node_init(&n, nt); - if (ret) - throw RuntimeError("Failed to initialize node"); + 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; - cfg = parse_cli(argc, argv, &format); - if (!cfg) { - usage(); - exit(EXIT_FAILURE); + ret = utils::signals_init(quit); + if (ret) + throw RuntimeError("Failed to intialize signals"); + + ret = memory_init(0); + if (ret) + throw RuntimeError("Failed to initialize memory"); + + nt = node_type_lookup("signal"); + if (!nt) + throw RuntimeError("Signal generation is not supported."); + + ret = node_init(&n, nt); + if (ret) + throw RuntimeError("Failed to initialize node"); + + cfg = parse_cli(argc, argv, &format); + if (!cfg) { + usage(); + exit(EXIT_FAILURE); + } + + ret = node_parse(&n, cfg, "cli"); + if (ret) { + usage(); + exit(EXIT_FAILURE); + } + + ft = format_type_lookup(format); + if (!ft) + throw RuntimeError("Invalid output format '{}'", format); + + // nt == n._vt + ret = node_type_start(nt, nullptr); + if (ret) + throw RuntimeError("Failed to initialize node type: {}", node_type_name(nt)); + + ret = node_check(&n); + 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"); + + ret = io_check(&io); + if (ret) + throw RuntimeError("Failed to validate IO configuration"); + + ret = io_open(&io, nullptr); + if (ret) + throw RuntimeError("Failed to open output"); + + while (!stop && n.state == STATE_STARTED) { + t = sample_alloc(&q); + + unsigned release = 1; // release = allocated + +retry: ret = node_read(&n, &t, 1, &release); + if (ret == 0) + goto retry; + else if (ret < 0) + goto out; + + io_print(&io, &t, 1); + +out: sample_decref(t); + } + + ret = node_stop(&n); + if (ret) + throw RuntimeError("Failed to stop node"); + + ret = node_destroy(&n); + if (ret) + throw RuntimeError("Failed to destroy node"); + + ret = io_close(&io); + if (ret) + throw RuntimeError("Failed to close IO"); + + ret = io_destroy(&io); + if (ret) + throw RuntimeError("Failed to destroy IO"); + + ret = pool_destroy(&q); + if (ret) + throw RuntimeError("Failed to destroy pool"); + + logger->info(CLR_GRN("Goodbye!")); + + return 0; } + catch (std::runtime_error &e) { + logger->error("{}", e.what()); - ret = node_parse(&n, cfg, "cli"); - if (ret) { - usage(); - exit(EXIT_FAILURE); + return -1; } - - ft = format_type_lookup(format); - if (!ft) - throw RuntimeError("Invalid output format '{}'", format); - - // nt == n._vt - ret = node_type_start(nt, nullptr); - if (ret) - throw RuntimeError("Failed to initialize node type: {}", node_type_name(nt)); - - ret = node_check(&n); - 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"); - - ret = io_check(&io); - if (ret) - throw RuntimeError("Failed to validate IO configuration"); - - ret = io_open(&io, nullptr); - if (ret) - throw RuntimeError("Failed to open output"); - - while (!stop && n.state == STATE_STARTED) { - t = sample_alloc(&q); - - unsigned release = 1; // release = allocated - -retry: ret = node_read(&n, &t, 1, &release); - if (ret == 0) - goto retry; - else if (ret < 0) - goto out; - - io_print(&io, &t, 1); - -out: sample_decref(t); - } - - ret = node_stop(&n); - if (ret) - throw RuntimeError("Failed to stop node"); - - ret = node_destroy(&n); - if (ret) - throw RuntimeError("Failed to destroy node"); - - ret = io_close(&io); - if (ret) - throw RuntimeError("Failed to close IO"); - - ret = io_destroy(&io); - if (ret) - throw RuntimeError("Failed to destroy IO"); - - ret = pool_destroy(&q); - if (ret) - throw RuntimeError("Failed to destroy pool"); - - logger->info(CLR_GRN("Goodbye!")); - - return 0; } /** @} */ diff --git a/src/villas-test-cmp.cpp b/src/villas-test-cmp.cpp index 942fa3522..63c09749d 100644 --- a/src/villas-test-cmp.cpp +++ b/src/villas-test-cmp.cpp @@ -117,138 +117,147 @@ static void usage() int main(int argc, char *argv[]) { - int ret, rc = 0; + Logger logger = logging.get("test-cmp"); - /* 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; + try { + int ret, rc = 0; - struct pool pool = { .state = STATE_DESTROYED }; + /* 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; - /* Parse Arguments */ - int c; - char *endptr; - while ((c = getopt (argc, argv, "he:vTsf:t:Vd:")) != -1) { - switch (c) { - case 'e': - epsilon = strtod(optarg, &endptr); - goto check; + struct pool pool = { .state = STATE_DESTROYED }; - case 'v': - flags &= ~SAMPLE_HAS_DATA; - break; + /* Parse Arguments */ + int c; + char *endptr; + while ((c = getopt (argc, argv, "he:vTsf:t:Vd:")) != -1) { + switch (c) { + case 'e': + epsilon = strtod(optarg, &endptr); + goto check; - case 'T': - flags &= ~SAMPLE_HAS_TS_ORIGIN; - break; + case 'v': + flags &= ~SAMPLE_HAS_DATA; + break; - case 's': - flags &= ~SAMPLE_HAS_SEQUENCE; - break; + case 'T': + flags &= ~SAMPLE_HAS_TS_ORIGIN; + break; - case 'f': - format = optarg; - break; + case 's': + flags &= ~SAMPLE_HAS_SEQUENCE; + break; - case 't': - dtypes = optarg; - break; + case 'f': + format = optarg; + break; - case 'V': - print_version(); - exit(EXIT_SUCCESS); + case 't': + dtypes = optarg; + break; - case 'd': - logging.setLevel(optarg); - break; + case 'V': + print_version(); + exit(EXIT_SUCCESS); - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); - } + case 'd': + logging.setLevel(optarg); + break; - continue; - -check: if (optarg == endptr) - throw RuntimeError("Failed to parse parse option argument '-{} {}'", c, optarg); - } - - if (argc - optind < 2) { - usage(); - exit(EXIT_FAILURE); - } - - int eofs, line, failed; - int n = argc - optind; /* The number of files which we compare */ - Side *s[n]; - - ret = memory_init(0); - if (ret) - throw RuntimeError("Failed to initialize memory system"); - - 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); - 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); - - 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); - if (ret) - eofs++; - } - - if (eofs) { - if (eofs == n) - ret = 0; - else { - std::cout << "length unequal" << std::endl; - rc = 1; + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); } - goto out; + continue; + +check: if (optarg == endptr) + throw RuntimeError("Failed to parse parse option argument '-{} {}'", c, optarg); } - failed = 0; - for (int i = 0; i < n; i++) { - ret = io_scan(&s[i]->io, &s[i]->sample, 1); - if (ret <= 0) - failed++; + if (argc - optind < 2) { + usage(); + exit(EXIT_FAILURE); } - if (failed) - 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); - if (ret) { - rc = ret; + int eofs, line, failed; + int n = argc - optind; /* The number of files which we compare */ + Side *s[n]; + + ret = memory_init(0); + if (ret) + throw RuntimeError("Failed to initialize memory system"); + + 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); + 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); + + 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); + if (ret) + eofs++; + } + + if (eofs) { + if (eofs == n) + ret = 0; + else { + std::cout << "length unequal" << std::endl; + rc = 1; + } + goto out; } + + failed = 0; + for (int i = 0; i < n; i++) { + ret = io_scan(&s[i]->io, &s[i]->sample, 1); + if (ret <= 0) + failed++; + } + if (failed) + 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); + if (ret) { + rc = ret; + goto out; + } + } + + line++; } - line++; +out: for (int i = 0; i < n; i++) + delete s[i]; + + ret = pool_destroy(&pool); + if (ret) + throw RuntimeError("Failed to destroy pool"); + + return rc; } + catch (std::runtime_error &e) { + logger->error("{}", e.what()); -out: for (int i = 0; i < n; i++) - delete s[i]; - - ret = pool_destroy(&pool); - if (ret) - throw RuntimeError("Failed to destroy pool"); - - return rc; + return -1; + } } diff --git a/src/villas-test-config.cpp b/src/villas-test-config.cpp index f1661b002..60ccf489a 100644 --- a/src/villas-test-config.cpp +++ b/src/villas-test-config.cpp @@ -47,35 +47,36 @@ static void usage() int main(int argc, char *argv[]) { - SuperNode sn; - Logger logger = logging.get("config-test"); - - bool check = false; - - int c; - while ((c = getopt (argc, argv, "hcV")) != -1) { - switch (c) { - case 'c': - check = true; - break; - - case 'V': - print_version(); - exit(EXIT_SUCCESS); - - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); - } - } - - if (argc - optind < 1) { - usage(); - exit(EXIT_FAILURE); - } + Logger logger = logging.get("test-config"); try { + SuperNode sn; + + bool check = false; + + int c; + while ((c = getopt (argc, argv, "hcV")) != -1) { + switch (c) { + case 'c': + check = true; + break; + + case 'V': + print_version(); + exit(EXIT_SUCCESS); + + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + } + } + + if (argc - optind < 1) { + usage(); + exit(EXIT_FAILURE); + } + sn.parse(argv[optind]); if (check) diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index 2aad22012..1fc060205 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -72,166 +72,174 @@ static void usage() int main(int argc, char *argv[]) { - int ret; - - 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; - - SuperNode sn; Logger logger = logging.get("test-rtt"); - /* Test options */ - int count = -1; /**< Amount of messages which should be sent (default: -1 for unlimited) */ + try { + int ret; - hist_cnt_t hist_warmup = 100; - int hist_buckets = 20; + struct hist hist; + struct timespec send, recv; - /** 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; + struct sample *smp_send = (struct sample *) new char[SAMPLE_LENGTH(2)]; + struct sample *smp_recv = (struct sample *) new char[SAMPLE_LENGTH(2)]; - /* Parse Arguments */ - int c; - char *endptr; - while ((c = getopt (argc, argv, "w:hr:f:c:b:Vd:")) != -1) { - switch (c) { - case 'c': - count = strtoul(optarg, &endptr, 10); - goto check; + struct node *node; - case 'f': - fd = strtoul(optarg, &endptr, 10); - goto check; + SuperNode sn; - case 'w': - hist_warmup = strtoul(optarg, &endptr, 10); - goto check; + /* Test options */ + int count = -1; /**< Amount of messages which should be sent (default: -1 for unlimited) */ - case 'b': - hist_buckets = strtoul(optarg, &endptr, 10); - goto check; + hist_cnt_t hist_warmup = 100; + int hist_buckets = 20; - case 'V': - print_version(); - exit(EXIT_SUCCESS); + /** 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; - case 'd': - logging.setLevel(optarg); - break; + /* Parse Arguments */ + int c; + char *endptr; + while ((c = getopt (argc, argv, "w:hr:f:c:b:Vd:")) != -1) { + switch (c) { + case 'c': + count = strtoul(optarg, &endptr, 10); + goto check; - case 'h': - case '?': - usage(); - exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + case 'f': + fd = strtoul(optarg, &endptr, 10); + goto check; + + case 'w': + hist_warmup = strtoul(optarg, &endptr, 10); + goto check; + + case 'b': + hist_buckets = strtoul(optarg, &endptr, 10); + goto check; + + case 'V': + print_version(); + exit(EXIT_SUCCESS); + + case 'd': + logging.setLevel(optarg); + break; + + case 'h': + case '?': + usage(); + exit(c == '?' ? EXIT_FAILURE : EXIT_SUCCESS); + } + + continue; + +check: if (optarg == endptr) + throw RuntimeError("Failed to parse parse option argument '-{} {}'", c, optarg); } - continue; + if (argc != optind + 2) { + usage(); + exit(EXIT_FAILURE); + } -check: if (optarg == endptr) - throw RuntimeError("Failed to parse parse option argument '-{} {}'", c, optarg); + char *uri = argv[optind]; + char *nodestr = argv[optind + 1]; + + ret = utils::signals_init(quit); + if (ret) + throw RuntimeError("Failed to initialize signals subsystem"); + + if (uri) + sn.parse(uri); + else + logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); + + node = sn.getNode(nodestr); + if (!node) + throw RuntimeError("There's no node with the name '{}'", nodestr); + + ret = node_type_start(node->_vt, reinterpret_cast(&sn)); + if (ret) + throw RuntimeError("Failed to start node-type {}: reason={}", node_type_name(node->_vt), ret); + + ret = node_prepare(node); + if (ret) + throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); + + ret = node_start(node); + 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"); + + while (!stop && (count < 0 || count--)) { + clock_gettime(CLOCK_ID, &send); + + unsigned release; + + release = 1; // release = allocated + node_write(node, &smp_send, 1, &release); /* Ping */ + + release = 1; // release = allocated + node_read(node, &smp_recv, 1, &release); /* Pong */ + + clock_gettime(CLOCK_ID, &recv); + + double rtt = time_delta(&recv, &send); + + if (rtt < 0) + logger->warn("Negative RTT: {}", rtt); + + hist_put(&hist, 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)); + } + + struct stat st; + if (!fstat(fd, &st)) { + FILE *f = fdopen(fd, "w"); + hist_dump_matlab(&hist, 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"); + + ret = node_stop(node); + if (ret) + throw RuntimeError("Failed to stop node {}: reason={}", node_name(node), ret); + + ret = node_type_stop(node->_vt); + if (ret) + throw RuntimeError("Failed to stop node-type {}: reason={}", node_type_name(node->_vt), ret); + + delete smp_send; + delete smp_recv; + + return 0; } + catch (std::runtime_error &e) { + logger->error("{}", e.what()); - if (argc != optind + 2) { - usage(); - exit(EXIT_FAILURE); + return -1; } - - char *uri = argv[optind]; - char *nodestr = argv[optind + 1]; - - ret = utils::signals_init(quit); - if (ret) - throw RuntimeError("Failed to initialize signals subsystem"); - - if (uri) - sn.parse(uri); - else - logger->warn("No configuration file specified. Starting unconfigured. Use the API to configure this instance."); - - node = sn.getNode(nodestr); - if (!node) - throw RuntimeError("There's no node with the name '{}'", nodestr); - - ret = node_type_start(node->_vt, reinterpret_cast(&sn)); - if (ret) - throw RuntimeError("Failed to start node-type {}: reason={}", node_type_name(node->_vt), ret); - - ret = node_prepare(node); - if (ret) - throw RuntimeError("Failed to start node {}: reason={}", node_name(node), ret); - - ret = node_start(node); - 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"); - - while (!stop && (count < 0 || count--)) { - clock_gettime(CLOCK_ID, &send); - - unsigned release; - - release = 1; // release = allocated - node_write(node, &smp_send, 1, &release); /* Ping */ - - release = 1; // release = allocated - node_read(node, &smp_recv, 1, &release); /* Pong */ - - clock_gettime(CLOCK_ID, &recv); - - double rtt = time_delta(&recv, &send); - - if (rtt < 0) - logger->warn("Negative RTT: {}", rtt); - - hist_put(&hist, 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)); - } - - struct stat st; - if (!fstat(fd, &st)) { - FILE *f = fdopen(fd, "w"); - hist_dump_matlab(&hist, 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"); - - ret = node_stop(node); - if (ret) - throw RuntimeError("Failed to stop node {}: reason={}", node_name(node), ret); - - ret = node_type_stop(node->_vt); - if (ret) - throw RuntimeError("Failed to stop node-type {}: reason={}", node_type_name(node->_vt), ret); - - delete smp_send; - delete smp_recv; - - return 0; }