From 3790cf30aad0cfe899acd91fe53334d00c917d45 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 11:13:34 +0100 Subject: [PATCH 01/29] changed Doxygen HTML extension to work with Mongoose HTTPd --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index c9c623918..704354980 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1030,7 +1030,7 @@ HTML_OUTPUT = html # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FILE_EXTENSION = .xhtml +HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a From 9a7028c886e7c16ea704c69f7642eedc4eb7945a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 11:14:47 +0100 Subject: [PATCH 02/29] added script to generate initram filesystems and grub --- contrib/liveusb/update_boot.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100755 contrib/liveusb/update_boot.sh diff --git a/contrib/liveusb/update_boot.sh b/contrib/liveusb/update_boot.sh new file mode 100755 index 000000000..f0c87ca0e --- /dev/null +++ b/contrib/liveusb/update_boot.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# author: Christian Berendt + +set -x + +for kernel in $(find /boot/vmlinuz*); do + version=$(basename $kernel) + version=${version#*-} + if [ ! -e /boot/initramfs-$version.img ]; then + sudo /usr/bin/dracut /boot/initramfs-$version.img $version + fi +done + +for image in $(find /boot/initramfs*); do + version=${image%.img} + version=${version#*initramfs-} + if [ ! -e /boot/vmlinuz-$version ]; then + sudo rm $image + fi +done + +/usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg + From cad7c6bb2585cff09e6b585ef0319455e54f9873 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 11:26:34 +0100 Subject: [PATCH 03/29] added a few configuration files for the LiveUSB image --- contrib/liveusb/etc/default/grub | 7 +++++++ contrib/liveusb/etc/hostname | 1 + contrib/liveusb/etc/hosts | 10 ++++++++++ .../liveusb/{ => etc/systemd/system}/dhclient.service | 0 contrib/liveusb/{ => etc/systemd/system}/setup.service | 0 contrib/liveusb/etc/tuned/active_profile | 1 + 6 files changed, 19 insertions(+) create mode 100644 contrib/liveusb/etc/default/grub create mode 100644 contrib/liveusb/etc/hostname create mode 100644 contrib/liveusb/etc/hosts rename contrib/liveusb/{ => etc/systemd/system}/dhclient.service (100%) rename contrib/liveusb/{ => etc/systemd/system}/setup.service (100%) create mode 100644 contrib/liveusb/etc/tuned/active_profile diff --git a/contrib/liveusb/etc/default/grub b/contrib/liveusb/etc/default/grub new file mode 100644 index 000000000..d3bd7ac6b --- /dev/null +++ b/contrib/liveusb/etc/default/grub @@ -0,0 +1,7 @@ +GRUB_TIMEOUT=5 +GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" +GRUB_DEFAULT=1 +GRUB_DISABLE_SUBMENU=false +GRUB_TERMINAL_OUTPUT="console" +GRUB_CMDLINE_LINUX="isolcpus=6,7 selinux=0 audit=0" +GRUB_DISABLE_RECOVERY=true diff --git a/contrib/liveusb/etc/hostname b/contrib/liveusb/etc/hostname new file mode 100644 index 000000000..da598be9b --- /dev/null +++ b/contrib/liveusb/etc/hostname @@ -0,0 +1 @@ +unknown-s2ss diff --git a/contrib/liveusb/etc/hosts b/contrib/liveusb/etc/hosts new file mode 100644 index 000000000..05fc89de2 --- /dev/null +++ b/contrib/liveusb/etc/hosts @@ -0,0 +1,10 @@ +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 + +# Orchestrator + +# ACS hosts +134.130.169.31 acs-s2ss +134.130.169.32 acs-gtfpga +137.226.160.69 acs-opal +137.226.160.115 acs-workstation diff --git a/contrib/liveusb/dhclient.service b/contrib/liveusb/etc/systemd/system/dhclient.service similarity index 100% rename from contrib/liveusb/dhclient.service rename to contrib/liveusb/etc/systemd/system/dhclient.service diff --git a/contrib/liveusb/setup.service b/contrib/liveusb/etc/systemd/system/setup.service similarity index 100% rename from contrib/liveusb/setup.service rename to contrib/liveusb/etc/systemd/system/setup.service diff --git a/contrib/liveusb/etc/tuned/active_profile b/contrib/liveusb/etc/tuned/active_profile new file mode 100644 index 000000000..239b12e08 --- /dev/null +++ b/contrib/liveusb/etc/tuned/active_profile @@ -0,0 +1 @@ +latency-performance From 24d1a204fd3e221c0e487daa8146a022f8106d2f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 11:26:59 +0100 Subject: [PATCH 04/29] started writing a script to build a LiveUSB image (early stage) --- contrib/liveusb/prepare.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 contrib/liveusb/prepare.sh diff --git a/contrib/liveusb/prepare.sh b/contrib/liveusb/prepare.sh new file mode 100644 index 000000000..eb7a9a755 --- /dev/null +++ b/contrib/liveusb/prepare.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +rpm -Uvh http://ccrma.stanford.edu/planetccrma/mirror/fedora/linux/planetccrma/20/i386/planetccrma-repo-1.1-3.fc20.ccrma.noarch.rpm + +yum update + +yum install planetccrma-core + +source update_boot.sh From d13f19834bbc16c8315b4ef683e554dfeb789af6 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 19 Mar 2015 17:57:11 +0100 Subject: [PATCH 05/29] improved setup script --- contrib/liveusb/setup.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/contrib/liveusb/setup.sh b/contrib/liveusb/setup.sh index 62c46b1c7..29bbff726 100755 --- a/contrib/liveusb/setup.sh +++ b/contrib/liveusb/setup.sh @@ -2,15 +2,14 @@ set -e -RECEIPENTS="stvogel@eonerc.rwth-aachen.de,mstevic@eonerc.rwth-aachen.de" -FROM="Simulator2Simulator Server " +RECIPIENTS="stvogel@eonerc.rwth-aachen.de,mstevic@eonerc.rwth-aachen.de" SERVER=tux.0l.de USER=acs PORT=$(shuf -i 60000-65535 -n 1) -IP=$(curl -s http://ifconfig.me) +IP=$(curl -s http://canihazip.com/s) # check if system has net connectivity. otherwise die... ssh -q -o ConnectTimeout=2 $USER@$SERVER @@ -21,7 +20,11 @@ ssh -f -N -L 25:localhost:25 $USER@$SERVER ssh -f -N -R $PORT:localhost:22 $USER@$SERVER # send mail with notification about new node -mail -s "New S2SS node alive: $IP ($HOSTNAME)" -a "From: $FROM" "$RECEIPENTS" < +To: $(RECIPIENTS) + There's a new host with the S2SS LiveUSB Image running: Reverse SSH tunnel port: $PORT From 721427ebf595d8383198db60de283630c9ff001f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 12:12:52 +0100 Subject: [PATCH 06/29] last fixes for Andrea's live image --- .../liveusb/etc/systemd/system/mongoose.service | 15 +++++++++++++++ contrib/liveusb/setup.sh | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 contrib/liveusb/etc/systemd/system/mongoose.service diff --git a/contrib/liveusb/etc/systemd/system/mongoose.service b/contrib/liveusb/etc/systemd/system/mongoose.service new file mode 100644 index 000000000..2ff7070d7 --- /dev/null +++ b/contrib/liveusb/etc/systemd/system/mongoose.service @@ -0,0 +1,15 @@ +[Unit] +Description=The mongoose Web server +After=network.target + +[Service] +Type=simple +User=nobody +Group=nobody +Restart=always +ExecStart=/usr/bin/mongoose -p 80 -r /var/www/ +StandardOutput=syslog +SyslogIdentifier=mongoose + +[Install] +WantedBy=multi-user.target diff --git a/contrib/liveusb/setup.sh b/contrib/liveusb/setup.sh index 29bbff726..cb42fa00a 100755 --- a/contrib/liveusb/setup.sh +++ b/contrib/liveusb/setup.sh @@ -23,7 +23,7 @@ ssh -f -N -R $PORT:localhost:22 $USER@$SERVER sendmail "$RECIPIENTS" < -To: $(RECIPIENTS) +To: $RECIPIENTS There's a new host with the S2SS LiveUSB Image running: From 23fddff6e88b7b2a2fd6703c6287115c88dc5f49 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 13:54:21 +0100 Subject: [PATCH 07/29] removed note to non-existent directory from README.txt --- clients/README.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/clients/README.txt b/clients/README.txt index 010463360..619e5fd7c 100644 --- a/clients/README.txt +++ b/clients/README.txt @@ -19,11 +19,6 @@ Date: Mid 2014 - End 2015 UDP protocol over the ML507 Ethernet interface. This is working! -- ml507_ppc440_plbv46_pcie - An unsuccessful attempt to use the RTDS PLB interface used by "ml507_gtfpga_ppc440_udp" - with the Xilinx PLBv46_PCIe bridge to allow direct PCIe access to the RTDS registers. - This does NOT work! - - opal Contains the implementation of an asynchronous process block for RT-LAB. This block allows exchanging messages with an S2SS server over UDP/TCP. From 22566e25a134ff1d3550a9cba8c763211685f5d4 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 18:54:06 +0100 Subject: [PATCH 08/29] renamed directory --- clients/{opal => opal_udp}/.project | 0 .../.settings/com.opalrt.rtlab.ui.application.prefs | 0 clients/{opal => opal_udp}/models/send_receive/include/config.h | 0 clients/{opal => opal_udp}/models/send_receive/include/msg.h | 0 .../{opal => opal_udp}/models/send_receive/include/msg_format.h | 0 clients/{opal => opal_udp}/models/send_receive/include/socket.h | 0 clients/{opal => opal_udp}/models/send_receive/include/utils.h | 0 clients/{opal => opal_udp}/models/send_receive/s2ss.mk | 0 clients/{opal => opal_udp}/models/send_receive/send_receive.llm | 0 clients/{opal => opal_udp}/models/send_receive/send_receive.mdl | 0 clients/{opal => opal_udp}/models/send_receive/src/msg.c | 0 clients/{opal => opal_udp}/models/send_receive/src/s2ss.c | 0 clients/{opal => opal_udp}/models/send_receive/src/socket.c | 0 clients/{opal => opal_udp}/models/send_receive/src/utils.c | 0 clients/{opal => opal_udp}/s2ss_tests.llp | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename clients/{opal => opal_udp}/.project (100%) rename clients/{opal => opal_udp}/.settings/com.opalrt.rtlab.ui.application.prefs (100%) rename clients/{opal => opal_udp}/models/send_receive/include/config.h (100%) rename clients/{opal => opal_udp}/models/send_receive/include/msg.h (100%) rename clients/{opal => opal_udp}/models/send_receive/include/msg_format.h (100%) rename clients/{opal => opal_udp}/models/send_receive/include/socket.h (100%) rename clients/{opal => opal_udp}/models/send_receive/include/utils.h (100%) rename clients/{opal => opal_udp}/models/send_receive/s2ss.mk (100%) rename clients/{opal => opal_udp}/models/send_receive/send_receive.llm (100%) rename clients/{opal => opal_udp}/models/send_receive/send_receive.mdl (100%) rename clients/{opal => opal_udp}/models/send_receive/src/msg.c (100%) rename clients/{opal => opal_udp}/models/send_receive/src/s2ss.c (100%) rename clients/{opal => opal_udp}/models/send_receive/src/socket.c (100%) rename clients/{opal => opal_udp}/models/send_receive/src/utils.c (100%) rename clients/{opal => opal_udp}/s2ss_tests.llp (100%) diff --git a/clients/opal/.project b/clients/opal_udp/.project similarity index 100% rename from clients/opal/.project rename to clients/opal_udp/.project diff --git a/clients/opal/.settings/com.opalrt.rtlab.ui.application.prefs b/clients/opal_udp/.settings/com.opalrt.rtlab.ui.application.prefs similarity index 100% rename from clients/opal/.settings/com.opalrt.rtlab.ui.application.prefs rename to clients/opal_udp/.settings/com.opalrt.rtlab.ui.application.prefs diff --git a/clients/opal/models/send_receive/include/config.h b/clients/opal_udp/models/send_receive/include/config.h similarity index 100% rename from clients/opal/models/send_receive/include/config.h rename to clients/opal_udp/models/send_receive/include/config.h diff --git a/clients/opal/models/send_receive/include/msg.h b/clients/opal_udp/models/send_receive/include/msg.h similarity index 100% rename from clients/opal/models/send_receive/include/msg.h rename to clients/opal_udp/models/send_receive/include/msg.h diff --git a/clients/opal/models/send_receive/include/msg_format.h b/clients/opal_udp/models/send_receive/include/msg_format.h similarity index 100% rename from clients/opal/models/send_receive/include/msg_format.h rename to clients/opal_udp/models/send_receive/include/msg_format.h diff --git a/clients/opal/models/send_receive/include/socket.h b/clients/opal_udp/models/send_receive/include/socket.h similarity index 100% rename from clients/opal/models/send_receive/include/socket.h rename to clients/opal_udp/models/send_receive/include/socket.h diff --git a/clients/opal/models/send_receive/include/utils.h b/clients/opal_udp/models/send_receive/include/utils.h similarity index 100% rename from clients/opal/models/send_receive/include/utils.h rename to clients/opal_udp/models/send_receive/include/utils.h diff --git a/clients/opal/models/send_receive/s2ss.mk b/clients/opal_udp/models/send_receive/s2ss.mk similarity index 100% rename from clients/opal/models/send_receive/s2ss.mk rename to clients/opal_udp/models/send_receive/s2ss.mk diff --git a/clients/opal/models/send_receive/send_receive.llm b/clients/opal_udp/models/send_receive/send_receive.llm similarity index 100% rename from clients/opal/models/send_receive/send_receive.llm rename to clients/opal_udp/models/send_receive/send_receive.llm diff --git a/clients/opal/models/send_receive/send_receive.mdl b/clients/opal_udp/models/send_receive/send_receive.mdl similarity index 100% rename from clients/opal/models/send_receive/send_receive.mdl rename to clients/opal_udp/models/send_receive/send_receive.mdl diff --git a/clients/opal/models/send_receive/src/msg.c b/clients/opal_udp/models/send_receive/src/msg.c similarity index 100% rename from clients/opal/models/send_receive/src/msg.c rename to clients/opal_udp/models/send_receive/src/msg.c diff --git a/clients/opal/models/send_receive/src/s2ss.c b/clients/opal_udp/models/send_receive/src/s2ss.c similarity index 100% rename from clients/opal/models/send_receive/src/s2ss.c rename to clients/opal_udp/models/send_receive/src/s2ss.c diff --git a/clients/opal/models/send_receive/src/socket.c b/clients/opal_udp/models/send_receive/src/socket.c similarity index 100% rename from clients/opal/models/send_receive/src/socket.c rename to clients/opal_udp/models/send_receive/src/socket.c diff --git a/clients/opal/models/send_receive/src/utils.c b/clients/opal_udp/models/send_receive/src/utils.c similarity index 100% rename from clients/opal/models/send_receive/src/utils.c rename to clients/opal_udp/models/send_receive/src/utils.c diff --git a/clients/opal/s2ss_tests.llp b/clients/opal_udp/s2ss_tests.llp similarity index 100% rename from clients/opal/s2ss_tests.llp rename to clients/opal_udp/s2ss_tests.llp From befdc520d012c56866432bfcf06a0cee9a4f6c12 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 20 Mar 2015 18:55:14 +0100 Subject: [PATCH 09/29] fixed various bugs during OPAL-RT tests --- server/Makefile.mk | 52 ++++++++++++++++++++++++++ server/etc/opal-shmem.conf | 28 ++++++++++++++ server/include/config.h | 1 + server/include/hist.h | 2 +- server/include/if.h | 4 ++ server/include/list.h | 2 +- server/include/utils.h | 48 ++++++++++++++++-------- server/src/cfg.c | 34 ++++++++--------- server/src/opal.c | 76 ++++++++++++++++++++------------------ server/src/server.c | 19 +++++++--- server/src/socket.c | 2 +- server/src/test.c | 2 +- server/src/utils.c | 6 +-- 13 files changed, 194 insertions(+), 82 deletions(-) create mode 100644 server/Makefile.mk create mode 100644 server/etc/opal-shmem.conf diff --git a/server/Makefile.mk b/server/Makefile.mk new file mode 100644 index 000000000..cad32cf05 --- /dev/null +++ b/server/Makefile.mk @@ -0,0 +1,52 @@ +TARGETS = server send random receive test + +# Common dependencies for all binaries +OBJS = socket.o if.o utils.o msg.o node.o cfg.o tc.o hooks.o list.o path.o hist.o + +VPATH = src + +# Default debug level +V ?= 2 + +# Compiler and linker flags +LDLIBS = -pthread -lrt -lm -lconfig +CFLAGS = -std=gnu99 -Iinclude/ -MMD -Wall +CFLAGS += -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -DV=$(V) +CFLAGS += -D__GIT_REV__='"-$(shell git rev-parse --short HEAD 2> /dev/null)"' + + +# Conditional flags +ifdef DEBUG + CFLAGS += -O0 -g -D_DEBUG +else + CFLAGS += -O3 +endif + +# Enable OPAL-RT Asynchronous Process support +OPALDIR = /usr/opalrt/common +ifneq (,$(wildcard $(OPALDIR)/include_target/AsyncApi.h)) + CFLAGS += -m32 -DENABLE_OPAL_ASYNC -I$(OPALDIR)/include_target + LDFLAGS += -m32 + LDLIBS += $(addprefix $(OPALDIR)/lib/redhawk/, libOpalAsyncApiCore.a libOpalCore.a libOpalUtils.a libirc.a) + OBJS += opal.o +endif + +.PHONY: all clean + +# Default target: build everything +all: $(TARGETS) + chmod 777 $(TARGETS) + +# Dependencies for individual binaries +server: server.o $(OBJS) +send: send.o $(OBJS) +receive: receive.o $(OBJS) +random: random.o $(OBJS) +test: test.o $(OBJS) + +clean: + $(RM) *~ *.o *.d + $(RM) $(TARGETS) + +# Include auto-generated dependencies +-include $(wildcard *.d) diff --git a/server/etc/opal-shmem.conf b/server/etc/opal-shmem.conf new file mode 100644 index 000000000..aa816dc0b --- /dev/null +++ b/server/etc/opal-shmem.conf @@ -0,0 +1,28 @@ +# Example configuration file for the s2ss server + +affinity = 0x01; # Mask of cores the server should run on +priority = 99; # Scheduler priority for the server +debug = 5; # The level of verbosity for debug messages +stats = 1; # The interval in seconds for path statistics + +nodes = { + opal = { + type = "opal"; + send_id = 1; + recv_id = 1; + }, + acs-s2ss = { + type = "udp"; + local = "*:12000"; + remote = "134.130.169.31:12000"; + } +}; + +paths = ( + { + in = "opal"; + out = "acs-s2ss"; + reverse = true; + hook = "print"; + } +); diff --git a/server/include/config.h b/server/include/config.h index c48558105..f5e306078 100644 --- a/server/include/config.h +++ b/server/include/config.h @@ -12,6 +12,7 @@ #define _CONFIG_H_ /** The version number of the s2ss server */ + #define VERSION "v0.4" __GIT_REV__ /** Maximum number of double values in a struct msg */ diff --git a/server/include/hist.h b/server/include/hist.h index 59a16e131..ecf8eca9e 100644 --- a/server/include/hist.h +++ b/server/include/hist.h @@ -76,4 +76,4 @@ void hist_dump(struct hist *h, char *buf, int len); /** Prints Matlab struct containing all infos to file. */ void hist_matlab(struct hist *h, FILE *f); -#endif /* _HIST_H_ */ \ No newline at end of file +#endif /* _HIST_H_ */ diff --git a/server/include/if.h b/server/include/if.h index a236e6bd3..1abe6e405 100644 --- a/server/include/if.h +++ b/server/include/if.h @@ -17,6 +17,10 @@ #define IF_NAME_MAX IFNAMSIZ /**< Maximum length of an interface name */ #define IF_IRQ_MAX 3 /**< Maxmimal number of IRQs of an interface */ +#ifndef SO_MARK +#define SO_MARK 36 /**< Workaround: add missing constant for OPAL-RT Redhawk target */ +#endif + struct socket; /** Interface data structure */ diff --git a/server/include/list.h b/server/include/list.h index 999365833..269404094 100644 --- a/server/include/list.h +++ b/server/include/list.h @@ -67,4 +67,4 @@ void list_push(struct list *l, void *p); struct list_elm * list_search(struct list *l, int (*cmp)(void *)); -#endif /* _LIST_H_ */ \ No newline at end of file +#endif /* _LIST_H_ */ diff --git a/server/include/utils.h b/server/include/utils.h index d20c5500b..9f4e34c7f 100644 --- a/server/include/utils.h +++ b/server/include/utils.h @@ -21,23 +21,41 @@ #endif /* Some color escape codes for pretty log messages */ -#define GRY(str) "\e[30m" str "\e[0m" /**< Print str in gray */ -#define RED(str) "\e[31m" str "\e[0m" /**< Print str in red */ -#define GRN(str) "\e[32m" str "\e[0m" /**< Print str in green */ -#define YEL(str) "\e[33m" str "\e[0m" /**< Print str in yellow */ -#define BLU(str) "\e[34m" str "\e[0m" /**< Print str in blue */ -#define MAG(str) "\e[35m" str "\e[0m" /**< Print str in magenta */ -#define CYN(str) "\e[36m" str "\e[0m" /**< Print str in cyan */ -#define WHT(str) "\e[37m" str "\e[0m" /**< Print str in white */ -#define BLD(str) "\e[1m" str "\e[0m" /**< Print str in bold */ +#ifndef ENABLE_OPAL_ASYNC + #define GRY(str) "\e[30m" str "\e[0m" /**< Print str in gray */ + #define RED(str) "\e[31m" str "\e[0m" /**< Print str in red */ + #define GRN(str) "\e[32m" str "\e[0m" /**< Print str in green */ + #define YEL(str) "\e[33m" str "\e[0m" /**< Print str in yellow */ + #define BLU(str) "\e[34m" str "\e[0m" /**< Print str in blue */ + #define MAG(str) "\e[35m" str "\e[0m" /**< Print str in magenta */ + #define CYN(str) "\e[36m" str "\e[0m" /**< Print str in cyan */ + #define WHT(str) "\e[37m" str "\e[0m" /**< Print str in white */ + #define BLD(str) "\e[1m" str "\e[0m" /**< Print str in bold */ -#define GFX(chr) "\e(0" chr "\e(B" -#define UP(n) "\e[" ## n ## "A" -#define DOWN(n) "\e[" ## n ## "B" -#define RIGHT(n) "\e[" ## n ## "C" -#define LEFT(n) "\e[" ## n ## "D" + #define GFX(chr) "\e(0" chr "\e(B" + #define UP(n) "\e[" ## n ## "A" + #define DOWN(n) "\e[" ## n ## "B" + #define RIGHT(n) "\e[" ## n ## "C" + #define LEFT(n) "\e[" ## n ## "D" +#else + #define GRY(str) str + #define RED(str) str + #define GRN(str) str + #define YEL(str) str + #define BLU(str) str + #define MAG(str) str + #define CYN(str) str + #define WHT(str) str + #define BLD(str) str -#define ARRAY_LEN(a) ( sizeof a / sizeof a[0] ) + #define GFX(chr) " " + #define UP(n) "" + #define DOWN(n) "" + #define RIGHT(n) "" + #define LEFT(n) "" +#endif + +#define ARRAY_LEN(a) ( sizeof (a) / sizeof (a)[0] ) #define SWAP(a, b) do { \ __typeof__(a) tmp = a; \ diff --git a/server/src/cfg.c b/server/src/cfg.c index 3060b3a56..632ce69b8 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -27,19 +27,16 @@ int config_parse(const char *filename, config_t *cfg, struct settings *set, { config_set_auto_convert(cfg, 1); - FILE *file = (strcmp("-", filename)) ? fopen(filename, "r") : stdin; - if (!file) - error("Failed to open configuration file: %s", filename); + int ret = strcmp("-", filename) ? config_read_file(cfg, filename) + : config_read(cfg, stdin); - if (!config_read(cfg, file)) + if (ret != CONFIG_TRUE) error("Failed to parse configuration: %s in %s:%d", - config_error_text(cfg), filename, + config_error_text(cfg), + config_error_file(cfg) ? config_error_file(cfg) : filename, config_error_line(cfg) ); - - if (file != stdin) - fclose(file); - + config_setting_t *cfg_root = config_root_setting(cfg); /* Parse global settings */ @@ -74,7 +71,7 @@ int config_parse(const char *filename, config_t *cfg, struct settings *set, } } - return CONFIG_TRUE; + return 0; } int config_parse_global(config_setting_t *cfg, struct settings *set) @@ -88,7 +85,7 @@ int config_parse_global(config_setting_t *cfg, struct settings *set) set->cfg = cfg; - return CONFIG_TRUE; + return 0; } int config_parse_path(config_setting_t *cfg, @@ -108,7 +105,7 @@ int config_parse_path(config_setting_t *cfg, in = config_setting_get_string(cfg_in); p->in = node_lookup_name(in, *nodes); if (!p->in) - cerror(cfg_in, "Invalid input node '%s", in); + cerror(cfg_in, "Invalid input node '%s'", in); /* Output node(s) */ struct config_setting_t *cfg_out = config_setting_get_member(cfg, "out"); @@ -257,7 +254,8 @@ int config_parse_node(config_setting_t *cfg, struct node **nodes) ret = n->vt->parse(cfg, n); - list_add(*nodes, n); + if (!ret) + list_add(*nodes, n); return ret; } @@ -268,7 +266,7 @@ extern struct opal_global *og; int config_parse_opal(config_setting_t *cfg, struct node *n) { if (!og) { - warn("Skipping this node, because this server is not running as an OPAL Async process!"); + warn("Skipping node '%s', because this server is not running as an OPAL Async process!", n->name); return -1; } @@ -279,7 +277,7 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) memset(o, 0, sizeof(struct opal)); config_setting_lookup_int(cfg, "send_id", &o->send_id); - config_setting_lookup_int(cfg, "recv_id", &o->send_id); + config_setting_lookup_int(cfg, "recv_id", &o->recv_id); config_setting_lookup_bool(cfg, "reply", &o->reply); /* Search for valid send and recv ids */ @@ -292,7 +290,7 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) if (!sfound) cerror(config_setting_get_member(cfg, "send_id"), "Invalid send_id '%u' for node '%s'", o->send_id, n->name); if (!rfound) - cerror(config_setting_get_member(cfg, "send_id"), "Invalid send_id '%u' for node '%s'", o->send_id, n->name); + cerror(config_setting_get_member(cfg, "recv_id"), "Invalid recv_id '%u' for node '%s'", o->recv_id, n->name); n->opal = o; n->opal->global = og; @@ -340,7 +338,7 @@ int config_parse_socket(config_setting_t *cfg, struct node *n) n->socket = s; - return CONFIG_TRUE; + return 0; } int config_parse_netem(config_setting_t *cfg, struct netem *em) @@ -362,5 +360,5 @@ int config_parse_netem(config_setting_t *cfg, struct netem *em) /** @todo Validate netem config values */ - return CONFIG_TRUE; + return 0; } diff --git a/server/src/opal.c b/server/src/opal.c index 44fb41a4a..24bc21d10 100644 --- a/server/src/opal.c +++ b/server/src/opal.c @@ -22,11 +22,7 @@ int opal_init(int argc, char *argv[]) if (argc != 4) return -1; - struct opal_global *g = (struct opal_global *) malloc(sizeof(struct opal_global)); - if (!g) - error("Failed to allocate memory for global OPAL settings"); - - memset(g, 0, sizeof(struct opal_global)); + struct opal_global *g = (struct opal_global *) alloc(sizeof(struct opal_global)); pthread_mutex_init(&g->lock, NULL); @@ -48,20 +44,20 @@ int opal_init(int argc, char *argv[]) /* Get list of Send and RecvIDs */ if ((err = OpalGetNbAsyncSendIcon(&g->send_icons)) != EOK) error("Failed to get number of send blocks (%d)", err); - if ((err = OpalGetNbAsyncRecvIcon(&g->recv_icons)) != EOK); + if ((err = OpalGetNbAsyncRecvIcon(&g->recv_icons)) != EOK) error("Failed to get number of recv blocks (%d)", err); - g->send_ids = (int *) malloc(g->send_icons * sizeof(int)); - g->recv_ids = (int *) malloc(g->recv_icons * sizeof(int)); - if (!g->send_ids || !g->recv_ids) - error("Failed to allocate memory for OPAL AsyncApi ID list."); + g->send_ids = alloc(g->send_icons * sizeof(int)); + g->recv_ids = alloc(g->recv_icons * sizeof(int)); - if ((err = OpalGetAsyncSendIDList(g->send_ids, g->send_icons)) != EOK) + if ((err = OpalGetAsyncSendIDList(g->send_ids, g->send_icons * sizeof(int))) != EOK) error("Failed to get list of send ids (%d)", err); - if ((err = OpalGetAsyncRecvIDList(g->recv_ids, g->recv_icons)) != EOK) + if ((err = OpalGetAsyncRecvIDList(g->recv_ids, g->recv_icons * sizeof(int))) != EOK) error("Failed to get list of recv ids (%d)", err); - info("Started as OPAL async process:"); + info("Started as OPAL Asynchronous process"); + info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s, debug=%d)", + VERSION, __DATE__, __TIME__, _debug); opal_print_global(g); og = g; @@ -73,18 +69,22 @@ int opal_deinit() { int err; - if (og) { - if ((err = OpalCloseAsyncMem(og->async_shmem_size, og->async_shmem_name)) != EOK) - error("Failed to close shared memory area (%d)", err); - if ((err = OpalSystemCtrl_UnRegister(og->print_shmem_name)) != EOK) - error("Failed to close shared memory for system control (%d)", err); + if (!og) + return 0; + + if ((err = OpalCloseAsyncMem(og->async_shmem_size, og->async_shmem_name)) != EOK) + error("Failed to close shared memory area (%d)", err); + + debug(4, "Closing OPAL shared memory mapping"); + + if ((err = OpalSystemCtrl_UnRegister(og->print_shmem_name)) != EOK) + error("Failed to close shared memory for system control (%d)", err); - free(og->send_ids); - free(og->recv_ids); - free(og); + free(og->send_ids); + free(og->recv_ids); + free(og); - og = NULL; - } + og = NULL; return 0; } @@ -99,15 +99,15 @@ int opal_print_global(struct opal_global *g) for (int i=0; irecv_icons; i++) strap(rbuf, sizeof(rbuf), "%u ", g->recv_ids[i]); - debug(4, "Controller ID: %u", g->params.controllerID); - debug(4, "Send Blocks: %s", sbuf); - debug(4, "Receive Blocks: %s", rbuf); + debug(2, "Controller ID: %u", g->params.controllerID); + debug(2, "Send Blocks: %s", sbuf); + debug(2, "Receive Blocks: %s", rbuf); - debug(4, "Control Block Parameters:"); + debug(2, "Control Block Parameters:"); for (int i=0; iparams.FloatParam[i]); + debug(2, "FloatParam[]%u] = %f", i, g->params.FloatParam[i]); for (int i=0; iparams.StringParam[i]); + debug(2, "StringParam[%u] = %s", i, g->params.StringParam[i]); return 0; } @@ -151,9 +151,9 @@ int opal_read(struct node *n, struct msg *m) do { if ((ret = OpalWaitForAsyncSendRequest(&id)) != EOK) { state = OpalGetAsyncModelState(); - if ((state != STATE_RESET) && (state != STATE_STOP)) { - OpalSetAsyncSendIconError(ret, id); - info("OpalWaitForAsyncSendRequest(), errno %d", ret); + if ((state == STATE_RESET) || (state == STATE_STOP)) { + info("OpalGetAsyncModelState(): Model stopped or resetted!"); + exit(0); } return -1; // FIXME: correct return value @@ -193,8 +193,10 @@ int opal_read(struct node *n, struct msg *m) /* 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)) - error("OpalGetAsyncModelState(): Model stopped or resetted!"); // TODO: fixme + if ((state == STATE_RESET) || (state == STATE_STOP)) { + info("OpalGetAsyncModelState(): Model stopped or resetted!"); + exit(0); + } return 0; } @@ -209,8 +211,10 @@ int opal_write(struct node *n, struct msg *m) double data[MSG_VALUES] = { NAN }; state = OpalGetAsyncModelState(); - if ((state == STATE_RESET) || (state == STATE_STOP)) - return -1; + if ((state == STATE_RESET) || (state == STATE_STOP)) { + info("OpalGetAsyncModelState(): Model stopped or resetted!"); + exit(0); + } OpalSetAsyncRecvIconStatus(m->sequence, o->recv_id); /* Set the Status to the message ID */ OpalSetAsyncRecvIconError(0, o->recv_id); /* Set the Error to 0 */ diff --git a/server/src/server.c b/server/src/server.c index 9513ca02e..68d5116b6 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -56,6 +56,10 @@ static void quit() } /** @todo Free nodes */ + +#ifdef ENABLE_OPAL_ASYNC + opal_deinit(); +#endif config_destroy(&config); @@ -71,11 +75,11 @@ void realtime_init() else info("Server is running on a realtime patched kernel"); - /* Use FIFO scheduler with realtime priority */ + /* Use FIFO scheduler with real time priority */ if (settings.priority) { struct sched_param param = { .sched_priority = settings.priority }; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) - serror("Failed to set realtime priority"); + serror("Failed to set real time priority"); else debug(3, "Set task priority to %u", settings.priority); } @@ -130,10 +134,8 @@ int main(int argc, char *argv[]) usage(argv[0]); epoch_reset(); - info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s)", - BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__))); - - char *configfile = argv[1]; + info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s, debug=%d)", + BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__)), _debug); /* Check priviledges */ if (getuid() != 0) @@ -150,6 +152,11 @@ int main(int argc, char *argv[]) #ifdef ENABLE_OPAL_ASYNC /* Check if called as asynchronous process from RT-LAB */ opal_init(argc, argv); + + char *configfile = "opal-shmem.conf"; +#else + + char *configfile = argv[1]; #endif /* Parse configuration and create nodes/paths */ diff --git a/server/src/socket.c b/server/src/socket.c index bfab7155e..0d9271a29 100644 --- a/server/src/socket.c +++ b/server/src/socket.c @@ -230,7 +230,7 @@ int socket_parse_addr(const char *addr, struct sockaddr *sa, enum node_type type else { /* Format: "192.168.0.10:12001" */ struct addrinfo hint = { .ai_flags = flags, - .ai_family = AF_UNSPEC + .ai_family = AF_INET }; /* Split string */ diff --git a/server/src/test.c b/server/src/test.c index 594732f36..d7a40021f 100644 --- a/server/src/test.c +++ b/server/src/test.c @@ -48,7 +48,7 @@ double high = 2e-4; /** Histogram resolution. */ double res = 1e-5; -#define CLOCK_ID CLOCK_MONOTONIC_RAW +#define CLOCK_ID CLOCK_MONOTONIC /* Prototypes */ void test_rtt(); diff --git a/server/src/utils.c b/server/src/utils.c index cfdbf0486..42798e420 100644 --- a/server/src/utils.c +++ b/server/src/utils.c @@ -16,6 +16,7 @@ #include #ifdef ENABLE_OPAL_ASYNC +#define RTLAB #include #endif @@ -89,10 +90,9 @@ void print(enum log_level lvl, const char *fmt, ...) /* Output */ #ifdef ENABLE_OPAL_ASYNC - OpalPrint("%s\n", buf); -#else - fprintf(stderr, "%s\n", buf); + OpalPrint("S2SS: %s\n", buf); #endif + fprintf(stderr, "%s\n", buf); } cpu_set_t to_cpu_set(int set) From a9795eda7c9e5a119fffde2147fbdd0791287b45 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 11:47:08 +0100 Subject: [PATCH 10/29] added missing #ifdefs when not compiling with OPAL_ASYNC support --- server/src/cfg.c | 7 +++++++ server/src/node.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/server/src/cfg.c b/server/src/cfg.c index 632ce69b8..21c01a28c 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -20,7 +20,9 @@ #include "socket.h" #include "gtfpga.h" +#ifdef ENABLE_OPAL_ASYNC #include "opal.h" +#endif int config_parse(const char *filename, config_t *cfg, struct settings *set, struct node **nodes, struct path **paths) @@ -260,6 +262,7 @@ int config_parse_node(config_setting_t *cfg, struct node **nodes) return ret; } +#ifdef ENABLE_OPAL_ASYNC /** @todo: Remove this global variable. */ extern struct opal_global *og; @@ -298,12 +301,16 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) return 0; } +#endif /* ENABLE_OPAL_ASYNC */ + +#ifdef ENABLE_GTFPGA /** @todo Implement */ int config_parse_gtfpga(config_setting_t *cfg, struct node *n) { return 0; } +#endif /* ENABLE_GTFPGA */ int config_parse_socket(config_setting_t *cfg, struct node *n) { diff --git a/server/src/node.c b/server/src/node.c index 28a5204c8..c14e5e878 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -13,7 +13,9 @@ /* Node types */ #include "socket.h" #include "gtfpga.h" +#ifdef ENABLE_OPAL_ASYNC #include "opal.h" +#endif #define VTABLE(type, name, fnc) { type, name, config_parse_ ## fnc, \ fnc ## _print, \ From d25ad21d86c35cea8497c09521663e377bf49392 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 11:54:14 +0100 Subject: [PATCH 11/29] removed last direct calls to malloc() --- server/src/cfg.c | 6 +----- server/src/hooks.c | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/server/src/cfg.c b/server/src/cfg.c index 21c01a28c..29bf57b1a 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -273,11 +273,7 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) return -1; } - struct opal *o = (struct opal *) malloc(sizeof(struct opal)); - if (!o) - error("Failed to allocate memory for opal settings"); - - memset(o, 0, sizeof(struct opal)); + struct opal *o = (struct opal *) alloc(sizeof(struct opal)); config_setting_lookup_int(cfg, "send_id", &o->send_id); config_setting_lookup_int(cfg, "recv_id", &o->recv_id); diff --git a/server/src/hooks.c b/server/src/hooks.c index 5a0607aff..3f5072e25 100644 --- a/server/src/hooks.c +++ b/server/src/hooks.c @@ -127,7 +127,7 @@ int hook_fir(struct msg *m, struct path *p) /* Create thread local storage for circular history buffer */ if (!history) { - history = malloc(len * sizeof(float)); + history = alloc(len * sizeof(float)); pthread_key_create(&pkey, free); pthread_setspecific(pkey, history); From 39f1dff62624bb816fea33562369f173e13ae0ae Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 12:28:17 +0100 Subject: [PATCH 12/29] fixed version string macro when git is not installed --- server/Makefile | 6 ++++-- server/include/config.h | 7 +++++-- server/include/utils.h | 6 ++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/server/Makefile b/server/Makefile index 0ca0dab1c..e8681c9cd 100644 --- a/server/Makefile +++ b/server/Makefile @@ -12,9 +12,11 @@ V ?= 2 LDLIBS = -pthread -lrt -lm -lconfig CFLAGS = -std=c99 -Iinclude/ -MMD -Wall CFLAGS += -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -DV=$(V) -CFLAGS += -D__GIT_REV__='"-$(shell git rev-parse --short HEAD)"' -# Conditional flags +# Add git commit hash +ifneq (,$(shell which git)) + CFLAGS += -D_GIT_REV='"$(shell git rev-parse --short HEAD)"' +endif ifdef DEBUG CFLAGS += -O0 -g else diff --git a/server/include/config.h b/server/include/config.h index f5e306078..b6002c26e 100644 --- a/server/include/config.h +++ b/server/include/config.h @@ -11,9 +11,12 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -/** The version number of the s2ss server */ +#ifndef _GIT_REV + #define _GIT_REV "nogit" +#endif -#define VERSION "v0.4" __GIT_REV__ +/** The version number of the s2ss server */ +#define VERSION "v0.4-" _GIT_REV /** Maximum number of double values in a struct msg */ #define MAX_VALUES 64 diff --git a/server/include/utils.h b/server/include/utils.h index 9f4e34c7f..90c233e34 100644 --- a/server/include/utils.h +++ b/server/include/utils.h @@ -55,8 +55,14 @@ #define LEFT(n) "" #endif +/* CPP stringification */ +#define XSTR(x) STR(x) +#define STR(x) #x + +/** Calculate the number of elements in an array. */ #define ARRAY_LEN(a) ( sizeof (a) / sizeof (a)[0] ) +/** Swap two values by using a local third one. */ #define SWAP(a, b) do { \ __typeof__(a) tmp = a; \ a = b; \ From 2bc21561710c86cdd4d489fd706d4230a6bac263 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 12:28:36 +0100 Subject: [PATCH 13/29] merged OPAL specific Makefile --- server/Makefile | 10 +++++---- server/Makefile.mk | 52 ---------------------------------------------- 2 files changed, 6 insertions(+), 56 deletions(-) delete mode 100644 server/Makefile.mk diff --git a/server/Makefile b/server/Makefile index e8681c9cd..44b79665d 100644 --- a/server/Makefile +++ b/server/Makefile @@ -10,13 +10,15 @@ V ?= 2 # Compiler and linker flags LDLIBS = -pthread -lrt -lm -lconfig -CFLAGS = -std=c99 -Iinclude/ -MMD -Wall +CFLAGS = -std=gnu99 -Iinclude/ -MMD -Wall CFLAGS += -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -DV=$(V) # Add git commit hash ifneq (,$(shell which git)) CFLAGS += -D_GIT_REV='"$(shell git rev-parse --short HEAD)"' endif + +# Conditional debug flags ifdef DEBUG CFLAGS += -O0 -g else @@ -24,13 +26,13 @@ else endif # Enable OPAL-RT Asynchronous Process support -#OPALDIR = /usr/opalrt/common -OPALDIR = ../opal +OPALDIR = /usr/opalrt/common +#OPALDIR = ../opal ifneq (,$(wildcard $(OPALDIR)/include_target/AsyncApi.h)) CFLAGS += -m32 -DENABLE_OPAL_ASYNC -I$(OPALDIR)/include_target LDFLAGS += -m32 LDLIBS += $(addprefix $(OPALDIR)/lib/redhawk/, libOpalAsyncApiCore.a libOpalCore.a libOpalUtils.a libirc.a) - COMMON += opal.o + OBJS += opal.o endif .PHONY: all clean diff --git a/server/Makefile.mk b/server/Makefile.mk deleted file mode 100644 index cad32cf05..000000000 --- a/server/Makefile.mk +++ /dev/null @@ -1,52 +0,0 @@ -TARGETS = server send random receive test - -# Common dependencies for all binaries -OBJS = socket.o if.o utils.o msg.o node.o cfg.o tc.o hooks.o list.o path.o hist.o - -VPATH = src - -# Default debug level -V ?= 2 - -# Compiler and linker flags -LDLIBS = -pthread -lrt -lm -lconfig -CFLAGS = -std=gnu99 -Iinclude/ -MMD -Wall -CFLAGS += -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -DV=$(V) -CFLAGS += -D__GIT_REV__='"-$(shell git rev-parse --short HEAD 2> /dev/null)"' - - -# Conditional flags -ifdef DEBUG - CFLAGS += -O0 -g -D_DEBUG -else - CFLAGS += -O3 -endif - -# Enable OPAL-RT Asynchronous Process support -OPALDIR = /usr/opalrt/common -ifneq (,$(wildcard $(OPALDIR)/include_target/AsyncApi.h)) - CFLAGS += -m32 -DENABLE_OPAL_ASYNC -I$(OPALDIR)/include_target - LDFLAGS += -m32 - LDLIBS += $(addprefix $(OPALDIR)/lib/redhawk/, libOpalAsyncApiCore.a libOpalCore.a libOpalUtils.a libirc.a) - OBJS += opal.o -endif - -.PHONY: all clean - -# Default target: build everything -all: $(TARGETS) - chmod 777 $(TARGETS) - -# Dependencies for individual binaries -server: server.o $(OBJS) -send: send.o $(OBJS) -receive: receive.o $(OBJS) -random: random.o $(OBJS) -test: test.o $(OBJS) - -clean: - $(RM) *~ *.o *.d - $(RM) $(TARGETS) - -# Include auto-generated dependencies --include $(wildcard *.d) From cccd0e69573a979e2bd5243006aaa40c7cec916d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:19:41 +0100 Subject: [PATCH 14/29] removed old Linux-like linked list implementation for nodes, paths, interfaces and sockets --- server/include/cfg.h | 8 +++---- server/include/if.h | 8 +++---- server/include/list.h | 3 ++- server/include/node.h | 6 ++--- server/include/path.h | 3 --- server/include/utils.h | 7 +----- server/src/cfg.c | 20 ++++++++-------- server/src/if.c | 16 ++++++------- server/src/node.c | 12 +++++----- server/src/path.c | 4 ++-- server/src/receive.c | 4 ++-- server/src/send.c | 4 ++-- server/src/server.c | 54 ++++++++++++++++++------------------------ server/src/socket.c | 2 +- server/src/test.c | 4 ++-- 15 files changed, 69 insertions(+), 86 deletions(-) diff --git a/server/include/cfg.h b/server/include/cfg.h index 8201489ff..8f097c749 100644 --- a/server/include/cfg.h +++ b/server/include/cfg.h @@ -51,7 +51,7 @@ struct settings { * @retval <0 Error. Something went wrong. */ int config_parse(const char *filename, config_t *cfg, struct settings *set, - struct node **nodes, struct path **paths); + struct list *nodes, struct list *paths); /** Parse the global section of a configuration file. * @@ -71,9 +71,9 @@ int config_parse_global(config_setting_t *cfg, struct settings *set); * @retval <0 Error. Something went wrong. */ int config_parse_path(config_setting_t *cfg, - struct path **paths, struct node **nodes); + struct list *paths, struct list *nodes); -int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct node **all); +int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct list *all); int config_parse_hooks(config_setting_t *cfg, struct list *hooks); @@ -85,7 +85,7 @@ int config_parse_hooks(config_setting_t *cfg, struct list *hooks); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int config_parse_node(config_setting_t *cfg, struct node **nodes); +int config_parse_node(config_setting_t *cfg, struct list *nodes); /** Parse node connection details for OPAL type * diff --git a/server/include/if.h b/server/include/if.h index 1abe6e405..551c8f7ad 100644 --- a/server/include/if.h +++ b/server/include/if.h @@ -14,6 +14,8 @@ #include #include +#include "list.h" + #define IF_NAME_MAX IFNAMSIZ /**< Maximum length of an interface name */ #define IF_IRQ_MAX 3 /**< Maxmimal number of IRQs of an interface */ @@ -35,9 +37,7 @@ struct interface { char irqs[IF_IRQ_MAX]; /** Linked list of associated sockets */ - struct socket *sockets; - /** Linked list pointer */ - struct interface *next; + struct list sockets; }; /** Add a new interface to the global list and lookup name, irqs... @@ -106,7 +106,7 @@ int if_getirqs(struct interface *i); */ int if_setaffinity(struct interface *i, int affinity); -/** Search the list of interfaces for a given index. +/** Search the global list of interfaces for a given index. * * @param index The interface index to search for * @param interfaces A linked list of all interfaces diff --git a/server/include/list.h b/server/include/list.h index 269404094..7ddca565b 100644 --- a/server/include/list.h +++ b/server/include/list.h @@ -53,8 +53,9 @@ struct list_elm { struct node *node; struct path *path; struct interface *interface; + struct socket *socket; hook_cb_t hook; - }; + } /* anonymous */; struct list_elm *prev, *next; }; diff --git a/server/include/node.h b/server/include/node.h index d3c186504..f0e42896f 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -20,6 +20,7 @@ #include "msg.h" #include "tc.h" +#include "list.h" /** Static node initialization */ #define NODE_INIT(n) { \ @@ -81,9 +82,6 @@ struct node /** A pointer to the libconfig object which instantiated this node */ config_setting_t *cfg; - - /** Linked list pointer */ - struct node *next; }; /** Connect and bind the UDP socket of this node. @@ -129,7 +127,7 @@ struct node_vtable const * node_lookup_vtable(const char *str); * @param nodes A linked list of all nodes * @return A pointer to the node or NULL if not found */ -struct node* node_lookup_name(const char *str, struct node *nodes); +struct node * node_lookup_name(const char *str, struct list *nodes); /** Reverse local and remote socket address. * This is usefull for the helper programs: send, receive, test diff --git a/server/include/path.h b/server/include/path.h index 78bc4432f..e49b14e09 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -64,9 +64,6 @@ struct path pthread_t sent_tid; /** A pointer to the libconfig object which instantiated this path */ config_setting_t *cfg; - - /** Linked list pointer */ - struct path *next; }; /** Start a path. diff --git a/server/include/utils.h b/server/include/utils.h index 90c233e34..dc4d2e8f3 100644 --- a/server/include/utils.h +++ b/server/include/utils.h @@ -126,12 +126,6 @@ struct timespec timespec_rate(double rate); /** A system(2) emulator with popen/pclose(2) and proper output handling */ int system2(const char* cmd, ...); -/** Append an element to a single linked list */ -#define list_add(list, elm) do { \ - elm->next = list; \ - list = elm; \ - } while (0) - /** Check assertion and exit if failed. */ #define assert(exp) do { \ if (EXPECT(!exp, 0)) { \ @@ -179,3 +173,4 @@ int system2(const char* cmd, ...); } while (0) #endif /* _UTILS_H_ */ + diff --git a/server/src/cfg.c b/server/src/cfg.c index 29bf57b1a..326b22d4e 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -25,7 +25,7 @@ #endif int config_parse(const char *filename, config_t *cfg, struct settings *set, - struct node **nodes, struct path **paths) + struct list *nodes, struct list *paths) { config_set_auto_convert(cfg, 1); @@ -91,7 +91,7 @@ int config_parse_global(config_setting_t *cfg, struct settings *set) } int config_parse_path(config_setting_t *cfg, - struct path **paths, struct node **nodes) + struct list *paths, struct list *nodes) { const char *in; int enabled = 1; @@ -105,7 +105,7 @@ int config_parse_path(config_setting_t *cfg, cerror(cfg, "Invalid input node for path"); in = config_setting_get_string(cfg_in); - p->in = node_lookup_name(in, *nodes); + p->in = node_lookup_name(in, nodes); if (!p->in) cerror(cfg_in, "Invalid input node '%s'", in); @@ -150,10 +150,10 @@ int config_parse_path(config_setting_t *cfg, r->in->refcnt++; r->out->refcnt++; - list_add(*paths, r); + list_push(paths, r); } - list_add(*paths, p); + list_push(paths, p); } else { char buf[33]; @@ -166,14 +166,14 @@ int config_parse_path(config_setting_t *cfg, return 0; } -int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct node **all) { +int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct list *all) { const char *str; struct node *node; switch (config_setting_type(cfg)) { case CONFIG_TYPE_STRING: str = config_setting_get_string(cfg); - node = node_lookup_name(str, *all); + node = node_lookup_name(str, all); if (!node) cerror(cfg, "Invalid outgoing node '%s'", str); @@ -183,7 +183,7 @@ int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct node case CONFIG_TYPE_ARRAY: for (int i=0; ivt->parse(cfg, n); if (!ret) - list_add(*nodes, n); + list_push(nodes, n); return ret; } diff --git a/server/src/if.c b/server/src/if.c index a8c99207d..6a6750e23 100644 --- a/server/src/if.c +++ b/server/src/if.c @@ -22,8 +22,8 @@ #include "socket.h" #include "utils.h" -/** Linked list of interfaces */ -struct interface *interfaces; +/** Linked list of interfaces. */ +struct list interfaces; struct interface * if_create(int index) { struct interface *i = alloc(sizeof(struct interface)); @@ -33,7 +33,7 @@ struct interface * if_create(int index) { debug(3, "Created interface '%s'", i->name, i->index, i->refcnt); - list_add(interfaces, i); + list_push(&interfaces, i); return i; } @@ -49,7 +49,8 @@ int if_start(struct interface *i, int affinity) { INDENT int mark = 0; - for (struct socket *s = i->sockets; s; s = s->next) { + FOREACH(&i->sockets, it) { + struct socket *s = it->socket; if (s->netem) { s->mark = 1 + mark++; @@ -171,10 +172,9 @@ int if_setaffinity(struct interface *i, int affinity) struct interface * if_lookup_index(int index) { - for (struct interface *i = interfaces; i; i = i->next) { - if (i->index == index) { - return i; - } + FOREACH(&interfaces, it) { + if (it->interface->index == index) + return it->interface; } return NULL; diff --git a/server/src/node.c b/server/src/node.c index c14e5e878..77868a031 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -36,14 +36,14 @@ static const struct node_vtable vtables[] = { VTABLE(TCPD, "tcpd", socket) }; -/** Linked list of nodes */ -struct node *nodes; +/** Linked list of nodes. */ +struct list nodes; -struct node * node_lookup_name(const char *str, struct node *nodes) +struct node * node_lookup_name(const char *str, struct list *nodes) { - for (struct node *n = nodes; n; n = n->next) { - if (!strcmp(str, n->name)) - return n; + FOREACH(nodes, it) { + if (!strcmp(str, it->node->name)) + return it->node; } return NULL; diff --git a/server/src/path.c b/server/src/path.c index a697ae2a0..7b121a94c 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -18,8 +18,8 @@ #define sigev_notify_thread_id _sigev_un._tid -/** Linked list of paths */ -struct path *paths; +/** Linked list of paths. */ +struct list paths; /** Send messages asynchronously */ static void * path_send(void *arg) diff --git a/server/src/receive.c b/server/src/receive.c index 18f131c0e..bce4cb900 100644 --- a/server/src/receive.c +++ b/server/src/receive.c @@ -24,7 +24,7 @@ static struct settings set; static struct msg msg = MSG_INIT(0); -extern struct node *nodes; +extern struct list nodes; static struct node *node; void quit(int sig, siginfo_t *si, void *ptr) @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) config_init(&config); config_parse(argv[optind], &config, &set, &nodes, NULL); - node = node_lookup_name(argv[optind+1], nodes); + node = node_lookup_name(argv[optind+1], &nodes); if (!node) error("There's no node with the name '%s'", argv[optind+1]); diff --git a/server/src/send.c b/server/src/send.c index 2dd7bae2a..a9897bb62 100644 --- a/server/src/send.c +++ b/server/src/send.c @@ -27,7 +27,7 @@ static struct settings set; static struct msg msg = MSG_INIT(0); static struct node *node; -extern struct node *nodes; +extern struct list nodes; void quit(int sig, siginfo_t *si, void *ptr) { @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) config_init(&config); config_parse(argv[optind], &config, &set, &nodes, NULL); - node = node_lookup_name(argv[optind+1], nodes); + node = node_lookup_name(argv[optind+1], &nodes); if (!node) error("There's no node with the name '%s'", argv[optind+1]); diff --git a/server/src/server.c b/server/src/server.c index 68d5116b6..f0f41f79f 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -27,11 +27,11 @@ #endif /** Linked list of nodes */ -extern struct node *nodes; +extern struct list nodes; /** Linked list of paths */ -extern struct path *paths; +extern struct list paths; /** Linked list of interfaces */ -extern struct interface *interfaces; +extern struct list interfaces; /** The global configuration */ struct settings settings; @@ -40,27 +40,25 @@ config_t config; static void quit() { _indent = 0; info("Stopping paths:"); - for (struct path *p = paths; p; p = p->next) { INDENT - path_stop(p); - path_destroy(p); - } + FOREACH(&paths, it) + path_stop(it->path); info("Stopping nodes:"); - for (struct node *n = nodes; n; n = n->next) { INDENT - node_stop(n); - } + FOREACH(&nodes, it) + node_stop(it->node); info("Stopping interfaces:"); - for (struct interface *i = interfaces; i; i = i->next) { INDENT - if_stop(i); - } + FOREACH(&interfaces, it) + if_stop(it->interface); - /** @todo Free nodes */ - #ifdef ENABLE_OPAL_ASYNC opal_deinit(); #endif + /* Freeing dynamically allocated memory */ + list_destroy(&paths); + list_destroy(&nodes); + list_destroy(&interfaces); config_destroy(&config); _exit(EXIT_SUCCESS); @@ -164,35 +162,29 @@ int main(int argc, char *argv[]) /* Connect all nodes and start one thread per path */ info("Starting nodes:"); - for (struct node *n = nodes; n; n = n->next) { INDENT - node_start(n); - } + FOREACH(&nodes, it) + node_start(it->node); info("Starting interfaces:"); - for (struct interface *i = interfaces; i; i = i->next) { INDENT - if_start(i, settings.affinity); - } + FOREACH(&interfaces, it) + if_start(it->interface, settings.affinity); - info("Starting pathes:"); - for (struct path *p = paths; p; p = p->next) { INDENT - path_start(p); - } + info("Starting paths:"); + FOREACH(&paths, it) + path_start(it->path); /* Run! */ if (settings.stats > 0) { - struct path *p = paths; - info("Runtime Statistics:"); info("%-32s : %-8s %-8s %-8s %-8s %-8s", "Source " MAG("=>") " Destination", "#Sent", "#Recv", "#Drop", "#Skip", "#Inval"); info("---------------------------------------------------------------------------"); - while (1) { + do { FOREACH(&paths, it) { usleep(settings.stats * 1e6); - path_stats(p); + path_print_stats(it->path); + } } while (1); - p = (p->next) ? p->next : paths; - } } else pause(); diff --git a/server/src/socket.c b/server/src/socket.c index 0d9271a29..9b6f8fd68 100644 --- a/server/src/socket.c +++ b/server/src/socket.c @@ -86,7 +86,7 @@ int socket_open(struct node *n) if (!i) i = if_create(index); - list_add(i->sockets, s); + list_push(&i->sockets, s); i->refcnt++; /* Set socket priority, QoS or TOS IP options */ diff --git a/server/src/test.c b/server/src/test.c index d7a40021f..58fb410cf 100644 --- a/server/src/test.c +++ b/server/src/test.c @@ -26,7 +26,7 @@ static struct settings set; static struct node *node; -extern struct node *nodes; +extern struct list nodes; /* Test options */ int running = 1; @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) config_init(&config); config_parse(argv[1], &config, &set, &nodes, NULL); - node = node_lookup_name(argv[3], nodes); + node = node_lookup_name(argv[3], &nodes); if (!node) error("There's no node with the name '%s'", argv[3]); From bc2aff818b2b7dd1228ad74b352fcc8f0e089d10 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:20:22 +0100 Subject: [PATCH 15/29] unlock mutex before destroying it! --- server/src/list.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/list.c b/server/src/list.c index d34c8beef..1b1a1a935 100644 --- a/server/src/list.c +++ b/server/src/list.c @@ -31,6 +31,7 @@ void list_destroy(struct list *l) elm = elm->next; } + pthread_mutex_unlock(&l->lock); pthread_mutex_destroy(&l->lock); } From f0db3e78970888c65629b34e7bd0903940a5860e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:23:57 +0100 Subject: [PATCH 16/29] added destructor function callback to list implementation --- server/include/if.h | 7 +++++++ server/include/list.h | 9 ++++++++- server/include/node.h | 9 +++++++++ server/include/path.h | 9 +++++++++ server/src/cfg.c | 4 ++-- server/src/if.c | 9 +++++++++ server/src/list.c | 10 +++++++--- server/src/node.c | 19 +++++++++++++++++++ server/src/path.c | 19 +++++++++++++++++-- server/src/server.c | 6 ++++++ 10 files changed, 93 insertions(+), 8 deletions(-) diff --git a/server/include/if.h b/server/include/if.h index 551c8f7ad..cca9b5e03 100644 --- a/server/include/if.h +++ b/server/include/if.h @@ -48,6 +48,13 @@ struct interface { */ struct interface * if_create(int index); + +/** Destroy interface by freeing dynamically allocated memory. + * + * @param i A pointer to the interface structure. + */ +void if_destroy(struct interface *i); + /** Start interface. * * This setups traffic controls queue discs, network emulation and diff --git a/server/include/list.h b/server/include/list.h index 7ddca565b..4c9f5d373 100644 --- a/server/include/list.h +++ b/server/include/list.h @@ -40,10 +40,17 @@ struct interface; #define list_last(list) ((list)->head) #define list_length(list) ((list)->count) +/** Callback to destroy list elements. + * + * @param data A pointer to the data which should be freed. + */ +typedef void (*dtor_cb_t)(void *data); + struct list { struct list_elm *head, *tail; int count; + dtor_cb_t destructor; pthread_mutex_t lock; }; @@ -60,7 +67,7 @@ struct list_elm { struct list_elm *prev, *next; }; -void list_init(struct list *l); +void list_init(struct list *l, dtor_cb_t dtor); void list_destroy(struct list *l); diff --git a/server/include/node.h b/server/include/node.h index f0e42896f..60a65241e 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -135,4 +135,13 @@ struct node * node_lookup_name(const char *str, struct list *nodes); * server and therefore the direction needs to be swapped. */ int node_reverse(struct node *n); +/** Create a node by allocating dynamic memory. */ +struct node * node_create(); + +/** Destroy node by freeing dynamically allocated memory. + * + * @param i A pointer to the interface structure. + */ +void node_destroy(struct node *n); + #endif /* _NODE_H_ */ diff --git a/server/include/path.h b/server/include/path.h index e49b14e09..040dce01a 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -66,6 +66,15 @@ struct path config_setting_t *cfg; }; +/** Create a path by allocating dynamic memory. */ +struct path * path_create(); + +/** Destroy path by freeing dynamically allocated memory. + * + * @param i A pointer to the path structure. + */ +void path_destroy(struct path *p); + /** Start a path. * * Start a new pthread for receiving/sending messages over this path. diff --git a/server/src/cfg.c b/server/src/cfg.c index 326b22d4e..1e4a0474c 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -140,7 +140,7 @@ int config_parse_path(config_setting_t *cfg, warn("Using first destination '%s' as source for reverse path. " "Ignoring remaining nodes", p->out->name); - struct path *r = alloc(sizeof(struct path)); + struct path *r = path_create(); r->in = p->out; /* Swap in/out */ r->out = p->in; @@ -235,7 +235,7 @@ int config_parse_node(config_setting_t *cfg, struct list *nodes) const char *type; int ret; - struct node *n = alloc(sizeof(struct node)); + struct node *n = node_create(); /* Required settings */ n->cfg = cfg; diff --git a/server/src/if.c b/server/src/if.c index 6a6750e23..6d341d41f 100644 --- a/server/src/if.c +++ b/server/src/if.c @@ -33,11 +33,20 @@ struct interface * if_create(int index) { debug(3, "Created interface '%s'", i->name, i->index, i->refcnt); + list_init(&i->sockets, NULL); list_push(&interfaces, i); return i; } +void if_destroy(struct interface *i) +{ + /* List members are freed by their belonging nodes. */ + list_destroy(&i->sockets); + + free(i); +} + int if_start(struct interface *i, int affinity) { INDENT if (!i->refcnt) { diff --git a/server/src/list.c b/server/src/list.c index 1b1a1a935..bfc5882cc 100644 --- a/server/src/list.c +++ b/server/src/list.c @@ -10,10 +10,11 @@ #include "utils.h" #include "list.h" -void list_init(struct list *l) +void list_init(struct list *l, dtor_cb_t dtor) { pthread_mutex_init(&l->lock, NULL); + l->destructor = dtor; l->count = 0; l->head = NULL; l->tail = NULL; @@ -26,9 +27,12 @@ void list_destroy(struct list *l) struct list_elm *elm = l->head; while (elm) { struct list_elm *tmp = elm; - free(tmp); - elm = elm->next; + + if (l->destructor) + l->destructor(tmp->ptr); + + free(tmp); } pthread_mutex_unlock(&l->lock); diff --git a/server/src/node.c b/server/src/node.c index 77868a031..e6252cb9d 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -121,4 +121,23 @@ int node_reverse(struct node *n) default: { } } return n->vt->open == socket_open; + +struct node * node_create() +{ + return alloc(sizeof(struct node)); +} + +void node_destroy(struct node *n) +{ + switch (n->vt->type) { + case IEEE_802_3: + case IP: + case UDP: + case TCP: + free(n->socket->netem); + default: { } + } + + free(n->socket); + free(n); } diff --git a/server/src/path.c b/server/src/path.c index 7b121a94c..c7f226ae9 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -215,10 +215,25 @@ int path_print(struct path *p, char *buf, int len) return 0; } -int path_destroy(struct path *p) +struct path * path_create() +{ + struct path *p = alloc(sizeof(struct path)); + + list_init(&p->destinations, NULL); + list_init(&p->hooks, NULL); + + hist_create(&p->histogram, -HIST_SEQ, +HIST_SEQ, 1); + + return p; +} + +void path_destroy(struct path *p) { list_destroy(&p->destinations); list_destroy(&p->hooks); + hist_destroy(&p->histogram); - return 0; + free(p->current); + free(p->previous); + free(p); } diff --git a/server/src/server.c b/server/src/server.c index f0f41f79f..0b56b5d3e 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -139,9 +139,15 @@ int main(int argc, char *argv[]) if (getuid() != 0) error("The server requires superuser privileges!"); + /* Initialize lists */ + list_init(&nodes, (dtor_cb_t) node_destroy); + list_init(&paths, (dtor_cb_t) path_destroy); + list_init(&interfaces, (dtor_cb_t) if_destroy); + /* Start initialization */ info("Initialize realtime system:"); realtime_init(); + info("Setup signals:"); signals_init(); info("Parsing configuration:"); From e1d7e0487d99e5b99b4029e695e77f3c3e4bed60 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:26:52 +0100 Subject: [PATCH 17/29] adjust histogram memory management function naming scheme --- server/include/hist.h | 4 ++-- server/src/hist.c | 4 ++-- server/src/path.c | 3 --- server/src/test.c | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/server/include/hist.h b/server/include/hist.h index ecf8eca9e..af26154e2 100644 --- a/server/include/hist.h +++ b/server/include/hist.h @@ -44,10 +44,10 @@ struct hist { }; /** Initialize struct hist with supplied values and allocate memory for buckets. */ -void hist_init(struct hist *h, double start, double end, double resolution); +void hist_create(struct hist *h, double start, double end, double resolution); /** Free the dynamically allocated memory. */ -void hist_free(struct hist *h); +void hist_destroy(struct hist *h); /** Reset all counters and values back to zero. */ void hist_reset(struct hist *h); diff --git a/server/src/hist.c b/server/src/hist.c index cb20c0940..361375c41 100644 --- a/server/src/hist.c +++ b/server/src/hist.c @@ -17,7 +17,7 @@ #define VAL(h, i) ((h)->low + (i) * (h)->resolution) #define INDEX(h, v) round((v - (h)->low) / (h)->resolution) -void hist_init(struct hist *h, double low, double high, double resolution) +void hist_create(struct hist *h, double low, double high, double resolution) { h->low = low; h->high = high; @@ -28,7 +28,7 @@ void hist_init(struct hist *h, double low, double high, double resolution) hist_reset(h); } -void hist_free(struct hist *h) +void hist_destroy(struct hist *h) { free(h->data); } diff --git a/server/src/path.c b/server/src/path.c index c7f226ae9..19f39c6b7 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -156,8 +156,6 @@ int path_start(struct path *p) info("Starting path: %s", buf); - hist_init(&p->histogram, -HIST_SEQ, +HIST_SEQ, 1); - /* At fixed rate mode, we start another thread for sending */ if (p->rate) pthread_create(&p->sent_tid, NULL, &path_send, (void *) p); @@ -183,7 +181,6 @@ int path_stop(struct path *p) if (p->sent || p->received) { path_stats(p); hist_print(&p->histogram); - hist_free(&p->histogram); } return 0; diff --git a/server/src/test.c b/server/src/test.c index 58fb410cf..18768f6b7 100644 --- a/server/src/test.c +++ b/server/src/test.c @@ -155,7 +155,7 @@ void test_rtt() { double avg = 0; struct hist histogram; - hist_init(&histogram, low, high, res); + hist_create(&histogram, low, high, res); #if 1 /* Print header */ fprintf(stdout, "%17s", "timestamp"); @@ -201,5 +201,5 @@ void test_rtt() { else error("Invalid file descriptor: %u", fd); - hist_free(&histogram); + hist_destroy(&histogram); } From 08c41db911dd6cd20c47e72226f8ea2c69d094ab Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:27:17 +0100 Subject: [PATCH 18/29] fixed missing first indention level --- server/src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/utils.c b/server/src/utils.c index 42798e420..4abf4d686 100644 --- a/server/src/utils.c +++ b/server/src/utils.c @@ -79,7 +79,7 @@ void print(enum log_level lvl, const char *fmt, ...) } /* Indention */ - for (int i = 0; i < _indent-1; i++) + for (int i = 0; i < _indent; i++) strap(buf, sizeof(buf), GFX("\x78") " "); strap(buf, sizeof(buf), GFX("\x74") " "); From b89f65debc87d35bf0133dbe673e690a62e62989 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:29:00 +0100 Subject: [PATCH 19/29] a lots of small cleanups --- server/include/if.h | 2 +- server/include/msg_format.h | 6 +++--- server/include/node.h | 2 +- server/src/cfg.c | 21 ++++++++------------- server/src/hooks.c | 3 +-- server/src/if.c | 3 ++- server/src/node.c | 8 ++++---- server/src/opal.c | 2 +- server/src/path.c | 4 +++- server/src/random.c | 2 +- server/src/server.c | 7 ++++--- server/src/socket.c | 4 ++-- 12 files changed, 31 insertions(+), 33 deletions(-) diff --git a/server/include/if.h b/server/include/if.h index cca9b5e03..931f20234 100644 --- a/server/include/if.h +++ b/server/include/if.h @@ -20,7 +20,7 @@ #define IF_IRQ_MAX 3 /**< Maxmimal number of IRQs of an interface */ #ifndef SO_MARK -#define SO_MARK 36 /**< Workaround: add missing constant for OPAL-RT Redhawk target */ + #define SO_MARK 36 /**< Workaround: add missing constant for OPAL-RT Redhawk target */ #endif struct socket; diff --git a/server/include/msg_format.h b/server/include/msg_format.h index 40c21453b..c3c188721 100644 --- a/server/include/msg_format.h +++ b/server/include/msg_format.h @@ -14,7 +14,7 @@ #define _BSD_SOURCE 1 #include #elif defined(__PPC__) /* Xilinx toolchain */ - #include + #include #endif #include "config.h" @@ -30,8 +30,8 @@ #define MSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ #define MSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ -#define MSG_ENDIAN_LITTLE 0 /**< Message values are in little endian format (float too!) */ -#define MSG_ENDIAN_BIG 1 /**< Message values are in bit endian format */ +#define MSG_ENDIAN_LITTLE 0 /**< Message values are in little endian format (float too!) */ +#define MSG_ENDIAN_BIG 1 /**< Message values are in bit endian format */ #if BYTE_ORDER == LITTLE_ENDIAN #define MSG_ENDIAN_HOST MSG_ENDIAN_LITTLE diff --git a/server/include/node.h b/server/include/node.h index 60a65241e..fe5ac91c9 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -133,7 +133,7 @@ struct node * node_lookup_name(const char *str, struct list *nodes); * This is usefull for the helper programs: send, receive, test * because they usually use the same configuration file as the * server and therefore the direction needs to be swapped. */ -int node_reverse(struct node *n); +void node_reverse(struct node *n); /** Create a node by allocating dynamic memory. */ struct node * node_create(); diff --git a/server/src/cfg.c b/server/src/cfg.c index 1e4a0474c..6a3cf53ba 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -243,19 +243,14 @@ int config_parse_node(config_setting_t *cfg, struct list *nodes) if (!n->name) cerror(cfg, "Missing node name"); - if (config_setting_lookup_string(cfg, "type", &type)) { - n->vt = node_lookup_vtable(type); - if (!n->vt) - cerror(cfg, "Invalid type for node '%s'", n->name); - - if (!n->vt->parse) - cerror(cfg, "Node type '%s' is not allowed in the config", type); - } - else - n->vt = node_lookup_vtable("udp"); + if (!config_setting_lookup_string(cfg, "type", &type)) + cerror(cfg, "Missing node name"); + + n->vt = node_lookup_vtable(type); + if (!n->vt) + cerror(cfg, "Invalid type for node '%s'", n->name); ret = n->vt->parse(cfg, n); - if (!ret) list_push(nodes, n); @@ -273,7 +268,7 @@ int config_parse_opal(config_setting_t *cfg, struct node *n) return -1; } - struct opal *o = (struct opal *) alloc(sizeof(struct opal)); + struct opal *o = alloc(sizeof(struct opal)); config_setting_lookup_int(cfg, "send_id", &o->send_id); config_setting_lookup_int(cfg, "recv_id", &o->recv_id); @@ -334,7 +329,7 @@ int config_parse_socket(config_setting_t *cfg, struct node *n) /** @todo Netem settings are not usable AF_UNIX */ config_setting_t *cfg_netem = config_setting_get_member(cfg, "netem"); if (cfg_netem) { - s->netem = (struct netem *) alloc(sizeof(struct netem)); + s->netem = alloc(sizeof(struct netem)); config_parse_netem(cfg_netem, s->netem); } diff --git a/server/src/hooks.c b/server/src/hooks.c index 3f5072e25..637328ce9 100644 --- a/server/src/hooks.c +++ b/server/src/hooks.c @@ -71,7 +71,7 @@ int hook_log(struct msg *m, struct path *p) if (file) debug(5, "Opened log file for path %s: %s", pstr, fstr); - pthread_key_create(&pkey, (void (*)(void *)) fclose); + pthread_key_create(&pkey, (dtor_cb_t) fclose); pthread_setspecific(pkey, file); } @@ -128,7 +128,6 @@ int hook_fir(struct msg *m, struct path *p) /* Create thread local storage for circular history buffer */ if (!history) { history = alloc(len * sizeof(float)); - pthread_key_create(&pkey, free); pthread_setspecific(pkey, history); } diff --git a/server/src/if.c b/server/src/if.c index 6d341d41f..64e7caf27 100644 --- a/server/src/if.c +++ b/server/src/if.c @@ -60,6 +60,7 @@ int if_start(struct interface *i, int affinity) int mark = 0; FOREACH(&i->sockets, it) { struct socket *s = it->socket; + if (s->netem) { s->mark = 1 + mark++; @@ -88,7 +89,7 @@ int if_start(struct interface *i, int affinity) int if_stop(struct interface *i) { INDENT - info("Stopping interface '%s'", i->name); + info("Stopping interface '%s'", i->name); { INDENT if_setaffinity(i, -1L); diff --git a/server/src/node.c b/server/src/node.c index e6252cb9d..2a6e71db4 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -60,7 +60,7 @@ struct node_vtable const * node_lookup_vtable(const char *str) } int node_start(struct node *n) -{ +{ INDENT if (!n->refcnt) { warn("Node '%s' is unused. Skipping...", n->name); return -1; @@ -98,7 +98,7 @@ int node_start_defer(struct node *n) } int node_stop(struct node *n) -{ +{ INDENT int ret; info("Stopping node '%s'", n->name); @@ -109,7 +109,7 @@ int node_stop(struct node *n) return ret; } -int node_reverse(struct node *n) +void node_reverse(struct node *n) { switch (n->vt->type) { case IEEE_802_3: @@ -120,7 +120,7 @@ int node_reverse(struct node *n) break; default: { } } - return n->vt->open == socket_open; +} struct node * node_create() { diff --git a/server/src/opal.c b/server/src/opal.c index 24bc21d10..11da0d17c 100644 --- a/server/src/opal.c +++ b/server/src/opal.c @@ -22,7 +22,7 @@ int opal_init(int argc, char *argv[]) if (argc != 4) return -1; - struct opal_global *g = (struct opal_global *) alloc(sizeof(struct opal_global)); + struct opal_global *g = alloc(sizeof(struct opal_global)); pthread_mutex_init(&g->lock, NULL); diff --git a/server/src/path.c b/server/src/path.c index 19f39c6b7..7a2a29b33 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -16,7 +16,9 @@ #include "utils.h" #include "path.h" -#define sigev_notify_thread_id _sigev_un._tid +#ifndef sigev_notify_thread_id + #define sigev_notify_thread_id _sigev_un._tid +#endif /** Linked list of paths. */ struct list paths; diff --git a/server/src/random.c b/server/src/random.c index 7e3849cd6..9350e4f2d 100644 --- a/server/src/random.c +++ b/server/src/random.c @@ -22,7 +22,7 @@ void tick(int sig, siginfo_t *si, void *ptr) { - struct msg *m = (struct msg*) si->si_value.sival_ptr; + struct msg *m = (struct msg *) si->si_value.sival_ptr; msg_random(m); msg_fprint(stdout, m); diff --git a/server/src/server.c b/server/src/server.c index 0b56b5d3e..ce0d7e3b2 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -150,16 +150,17 @@ int main(int argc, char *argv[]) info("Setup signals:"); signals_init(); + info("Parsing configuration:"); config_init(&config); #ifdef ENABLE_OPAL_ASYNC - /* Check if called as asynchronous process from RT-LAB */ + /* Check if called we are called as an asynchronous process from RT-LAB. */ opal_init(argc, argv); - + + /* @todo: look in predefined locations for a file */ char *configfile = "opal-shmem.conf"; #else - char *configfile = argv[1]; #endif diff --git a/server/src/socket.c b/server/src/socket.c index 9b6f8fd68..3e4fc85d6 100644 --- a/server/src/socket.c +++ b/server/src/socket.c @@ -34,8 +34,8 @@ int socket_print(struct node *n, char *buf, int len) char local[INET6_ADDRSTRLEN + 16]; char remote[INET6_ADDRSTRLEN + 16]; - socket_print_addr(local, sizeof(local), (struct sockaddr*) &s->local); - socket_print_addr(remote, sizeof(remote), (struct sockaddr*) &s->remote); + socket_print_addr(local, sizeof(local), (struct sockaddr *) &s->local); + socket_print_addr(remote, sizeof(remote), (struct sockaddr *) &s->remote); return snprintf(buf, len, "local=%s, remote=%s", local, remote); } From b3d1fc8c457344ec1766dd1a504f93da2e98af1a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:30:42 +0100 Subject: [PATCH 20/29] added missing timer_delete() --- server/include/path.h | 2 ++ server/src/path.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/server/include/path.h b/server/include/path.h index 040dce01a..ce51ebd40 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -58,6 +58,8 @@ struct path /** Counter for dropped messages due to reordering */ unsigned int dropped; + /** A timer used for fixed rate transmission. */ + timer_t timer; /** The thread id for this path */ pthread_t recv_tid; /** A second thread id for fixed rate sending thread */ diff --git a/server/src/path.c b/server/src/path.c index 7a2a29b33..1cb8aea56 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -26,9 +26,9 @@ struct list paths; /** Send messages asynchronously */ static void * path_send(void *arg) { + struct path *p = arg; + int sig; - struct path *p = (struct path *) arg; - timer_t tmr; sigset_t set; struct sigevent sev = { @@ -47,10 +47,10 @@ static void * path_send(void *arg) if(pthread_sigmask(SIG_BLOCK, &set, NULL)) serror("Set signal mask"); - if (timer_create(CLOCK_REALTIME, &sev, &tmr)) + if (timer_create(CLOCK_REALTIME, &sev, &p->timer)) serror("Failed to create timer"); - if (timer_settime(tmr, 0, &its, NULL)) + if (timer_settime(p->timer, 0, &its, NULL)) serror("Failed to start timer"); while (1) { @@ -178,6 +178,8 @@ int path_stop(struct path *p) if (p->rate) { pthread_cancel(p->sent_tid); pthread_join(p->sent_tid, NULL); + + timer_delete(p->timer); } if (p->sent || p->received) { From 57081daa93c6aaff962b59b40511277ee0272c54 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:31:42 +0100 Subject: [PATCH 21/29] more cleanups --- server/include/path.h | 18 ++++++++++++------ server/src/path.c | 15 ++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/server/include/path.h b/server/include/path.h index ce51ebd40..e113bc69a 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -81,7 +81,7 @@ void path_destroy(struct path *p); * * Start a new pthread for receiving/sending messages over this path. * - * @param p A pointer to the path struct + * @param p A pointer to the path structure. * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ @@ -89,7 +89,7 @@ int path_start(struct path *p); /** Stop a path. * - * @param p A pointer to the path struct + * @param p A pointer to the path structure. * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ @@ -97,12 +97,18 @@ int path_stop(struct path *p); /** Show some basic statistics for a path. * - * @param p A pointer to the path struct + * @param p A pointer to the path structure. */ -void path_stats(struct path *p); +void path_print_stats(struct path *p); +/** Fills the provided buffer with a string representation of the path. + * + * Format: source => [ dest1 dest2 dest3 ] + * + * @param p A pointer to the path structure. + * @param buf A pointer to the buffer which should be filled. + * @param len The length of buf in bytes. + */ int path_print(struct path *p, char *buf, int len); -int path_destroy(struct path *p); - #endif /* _PATH_H_ */ diff --git a/server/src/path.c b/server/src/path.c index 1cb8aea56..1db24ee0a 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -74,8 +74,6 @@ static void * path_run(void *arg) char buf[33]; struct path *p = arg; struct msg *m = alloc(sizeof(struct msg)); - if (!m) - error("Failed to allocate memory for message!"); /* Open deferred TCP connection */ node_start_defer(p->in); @@ -160,9 +158,9 @@ int path_start(struct path *p) /* At fixed rate mode, we start another thread for sending */ if (p->rate) - pthread_create(&p->sent_tid, NULL, &path_send, (void *) p); + pthread_create(&p->sent_tid, NULL, &path_send, p); - return pthread_create(&p->recv_tid, NULL, &path_run, (void *) p); + return pthread_create(&p->recv_tid, NULL, &path_run, p); } int path_stop(struct path *p) @@ -183,21 +181,20 @@ int path_stop(struct path *p) } if (p->sent || p->received) { - path_stats(p); + path_print_stats(p); hist_print(&p->histogram); } return 0; } -void path_stats(struct path *p) +void path_print_stats(struct path *p) { char buf[33]; path_print(p, buf, sizeof(buf)); - info("%-32s : %-8u %-8u %-8u %-8u %-8u", - buf, p->sent, p->received, p->dropped, p->skipped, p->invalid - ); + info("%-32s : %-8u %-8u %-8u %-8u %-8u", buf, + p->sent, p->received, p->dropped, p->skipped, p->invalid); } int path_print(struct path *p, char *buf, int len) From 5f95fef0374e964e16e8cf51e79c678ecca2e2db Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 15:32:19 +0100 Subject: [PATCH 22/29] decreased maximum number of values per message to 16 (shrink working set) --- server/include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/include/config.h b/server/include/config.h index b6002c26e..7fb0cda5b 100644 --- a/server/include/config.h +++ b/server/include/config.h @@ -19,7 +19,7 @@ #define VERSION "v0.4-" _GIT_REV /** Maximum number of double values in a struct msg */ -#define MAX_VALUES 64 +#define MAX_VALUES 16 /** Socket priority */ #define SOCKET_PRIO 7 From f2734a395e4bc2ad669a5fbffd833f919ee9ff57 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 18:03:29 +0100 Subject: [PATCH 23/29] splitted debug/log system out of utils and made it thread safe :-) --- server/Makefile | 2 +- server/include/log.h | 70 +++++++++++++++++++++++++++++++++++++++ server/include/path.h | 7 ++-- server/include/utils.h | 74 +++++++----------------------------------- server/src/log.c | 69 +++++++++++++++++++++++++++++++++++++++ server/src/opal.c | 6 ++-- server/src/server.c | 12 +++---- server/src/utils.c | 53 +++--------------------------- 8 files changed, 168 insertions(+), 125 deletions(-) create mode 100644 server/include/log.h create mode 100644 server/src/log.c diff --git a/server/Makefile b/server/Makefile index 44b79665d..88f35adbb 100644 --- a/server/Makefile +++ b/server/Makefile @@ -1,7 +1,7 @@ TARGETS = server send random receive test # Common dependencies for all binaries -OBJS = socket.o if.o utils.o msg.o node.o cfg.o tc.o hooks.o list.o path.o hist.o +OBJS = socket.o if.o utils.o msg.o node.o cfg.o tc.o hooks.o list.o path.o hist.o log.o VPATH = src diff --git a/server/include/log.h b/server/include/log.h new file mode 100644 index 000000000..5baf35b13 --- /dev/null +++ b/server/include/log.h @@ -0,0 +1,70 @@ +#ifndef _LOG_H_ +#define _LOG_H_ + +#ifdef __GNUC__ + #define INDENT int __attribute__ ((__cleanup__(log_outdent), unused)) _old_indent = log_indent(1); +#else + #define INDENT ; +#endif + +/** Global debug level used by the debug() macro. + * It defaults to V (defined by the Makefile) and can be + * overwritten by the 'debug' setting in the config file. + */ +extern int _debug; + +/** The log level which is passed as first argument to print() */ +enum log_level { + DEBUG, + INFO, + WARN, + ERROR +}; + +int log_indent(int levels); + +void log_outdent(int *); + +/** Reset the wallclock of debugging outputs */ +void log_reset(); + +/** Logs variadic messages to stdout. + * + * @param lvl The log level + * @param fmt The format string (printf alike) + */ +void log_print(enum log_level lvl, const char *fmt, ...) + __attribute__ ((format(printf, 2, 3))); + +/** Printf alike debug message with level. */ +#define debug(lvl, msg, ...) do if (lvl <= _debug) log_print(DEBUG, msg, ##__VA_ARGS__); while (0) + +/** Printf alike info message. */ +#define info(msg, ...) do log_print(INFO, msg, ##__VA_ARGS__); while (0) + +/** Printf alike warning message. */ +#define warn(msg, ...) do log_print(WARN, msg, ##__VA_ARGS__); while (0) + +/** Print error and exit. */ +#define error(msg, ...) do { \ + log_print(ERROR, msg, ##__VA_ARGS__); \ + die(); \ + } while (0) + +/** Print error and strerror(errno). */ +#define serror(msg, ...) do { \ + log_print(ERROR, msg ": %s", ##__VA_ARGS__, strerror(errno)); \ + die(); \ + } while (0) + +/** Print configuration error and exit. */ +#define cerror(c, msg, ...) do { \ + log_print(ERROR, msg " in %s:%u", ##__VA_ARGS__, \ + (config_setting_source_file(c)) ? \ + config_setting_source_file(c) : "(stdio)", \ + config_setting_source_line(c)); \ + die(); \ + } while (0) + +#endif /* _LOG_H_ */ + diff --git a/server/include/path.h b/server/include/path.h index e113bc69a..4195855c7 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -39,14 +39,13 @@ struct path double rate; /** A pointer to the last received message */ - struct msg *last; + struct msg *current; + /** A pointer to the previously received message */ + struct msg *previous; /** Counter for received messages according to their sequence no displacement */ struct hist histogram; - /** Last known message number */ - unsigned int sequence; - /** Counter for sent messages to all outgoing nodes */ unsigned int sent; /** Counter for received messages from all incoming nodes */ diff --git a/server/include/utils.h b/server/include/utils.h index dc4d2e8f3..fce60c599 100644 --- a/server/include/utils.h +++ b/server/include/utils.h @@ -13,6 +13,9 @@ #include #include #include +#include + +#include "log.h" #ifdef __GNUC__ #define EXPECT(x, v) __builtin_expect(x, v) @@ -69,34 +72,16 @@ b = tmp; \ } while(0) -/** The log level which is passed as first argument to print() */ -enum log_level { DEBUG, INFO, WARN, ERROR }; - /* Forward declarations */ struct settings; struct timespec; -/* These global variables allow changing the output style and verbosity */ -extern int _debug; -extern int _indent; - -void outdent(int *old); - -#ifdef __GNUC__ - #define INDENT int __attribute__ ((__cleanup__(outdent), unused)) _old_indent = _indent++; -#else - #define INDENT ; -#endif - -/** Reset the wallclock of debugging outputs */ -void epoch_reset(); - -/** Logs variadic messages to stdout. - * - * @param lvl The log level - * @param fmt The format string (printf alike) +/** The main thread id. + * This is used to notify the main thread about + * the program termination. + * See error() macros. */ -void print(enum log_level lvl, const char *fmt, ...); +extern pthread_t _mtid; /** Safely append a format string to an existing string. * @@ -123,9 +108,12 @@ double timespec_delta(struct timespec *start, struct timespec *end); /** Get period as timespec from rate */ struct timespec timespec_rate(double rate); -/** A system(2) emulator with popen/pclose(2) and proper output handling */ +/** A system(2) emulator with popen / pclose(2) and proper output handling */ int system2(const char* cmd, ...); +/** Call quit() in the main thread. */ +void die(); + /** Check assertion and exit if failed. */ #define assert(exp) do { \ if (EXPECT(!exp, 0)) { \ @@ -134,43 +122,5 @@ int system2(const char* cmd, ...); exit(EXIT_FAILURE); \ } } while (0) -/** Printf alike debug message with level. */ -#define debug(lvl, msg, ...) do { \ - if (lvl <= _debug) \ - print(DEBUG, msg, ##__VA_ARGS__); \ - } while (0) - -/** Printf alike info message. */ -#define info(msg, ...) do { \ - print(INFO, msg, ##__VA_ARGS__); \ - } while (0) - -/** Printf alike warning message. */ -#define warn(msg, ...) do { \ - print(WARN, msg, ##__VA_ARGS__); \ - } while (0) - -/** Print error and exit. */ -#define error(msg, ...) do { \ - print(ERROR, msg, ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } while (0) - -/** Print error and strerror(errno). */ -#define serror(msg, ...) do { \ - print(ERROR, msg ": %s", ##__VA_ARGS__, \ - strerror(errno)); \ - exit(EXIT_FAILURE); \ - } while (0) - -/** Print configuration error and exit. */ -#define cerror(c, msg, ...) do { \ - print(ERROR, msg " in %s:%u", ##__VA_ARGS__, \ - (config_setting_source_file(c)) ? \ - config_setting_source_file(c) : "(stdio)", \ - config_setting_source_line(c)); \ - exit(EXIT_FAILURE); \ - } while (0) - #endif /* _UTILS_H_ */ diff --git a/server/src/log.c b/server/src/log.c new file mode 100644 index 000000000..c41c858d3 --- /dev/null +++ b/server/src/log.c @@ -0,0 +1,69 @@ +#include +#include + +#include "log.h" +#include "utils.h" + +int _debug = V; + +static struct timespec epoch; + +#ifdef __GNUC__ +static __thread int indent = 0; + +/** Get thread-specific pointer to indent level */ +int log_indent(int levels) +{ + int old = indent; + indent += levels; + return old; +} + +void log_outdent(int *old) +{ + indent = *old; +} +#endif + +void log_reset() +{ + clock_gettime(CLOCK_REALTIME, &epoch); +} + +void log_print(enum log_level lvl, const char *fmt, ...) +{ + struct timespec ts; + char buf[512] = ""; + + va_list ap; + + /* Timestamp */ + clock_gettime(CLOCK_REALTIME, &ts); + strap(buf, sizeof(buf), "%8.3f ", timespec_delta(&epoch, &ts)); + + /* Severity */ + switch (lvl) { + case DEBUG: strap(buf, sizeof(buf), BLD("%-5s "), GRY("Debug")); break; + case INFO: strap(buf, sizeof(buf), BLD("%-5s "), " " ); break; + case WARN: strap(buf, sizeof(buf), BLD("%-5s "), YEL(" Warn")); break; + case ERROR: strap(buf, sizeof(buf), BLD("%-5s "), RED("Error")); break; + } + + /* Indention */ +#ifdef __GNUC__ + for (int i = 0; i < indent; i++) + strap(buf, sizeof(buf), GFX("\x78") " "); + strap(buf, sizeof(buf), GFX("\x74") " "); +#endif + + /* Format String */ + va_start(ap, fmt); + vstrap(buf, sizeof(buf), fmt, ap); + va_end(ap); + + /* Output */ +#ifdef ENABLE_OPAL_ASYNC + OpalPrint("S2SS: %s\n", buf); +#endif + fprintf(stderr, "\r%s\n", buf); +} diff --git a/server/src/opal.c b/server/src/opal.c index 11da0d17c..f97e06c0c 100644 --- a/server/src/opal.c +++ b/server/src/opal.c @@ -153,7 +153,7 @@ int opal_read(struct node *n, struct msg *m) state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) { info("OpalGetAsyncModelState(): Model stopped or resetted!"); - exit(0); + die(); } return -1; // FIXME: correct return value @@ -195,7 +195,7 @@ int opal_read(struct node *n, struct msg *m) state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) { info("OpalGetAsyncModelState(): Model stopped or resetted!"); - exit(0); + die(); } return 0; @@ -213,7 +213,7 @@ int opal_write(struct node *n, struct msg *m) state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) { info("OpalGetAsyncModelState(): Model stopped or resetted!"); - exit(0); + die(); } OpalSetAsyncRecvIconStatus(m->sequence, o->recv_id); /* Set the Status to the message ID */ diff --git a/server/src/server.c b/server/src/server.c index ce0d7e3b2..f352f4b86 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -38,7 +38,7 @@ struct settings settings; config_t config; static void quit() -{ _indent = 0; +{ info("Stopping paths:"); FOREACH(&paths, it) path_stop(it->path); @@ -103,7 +103,6 @@ void signals_init() sigemptyset(&sa_quit.sa_mask); sigaction(SIGTERM, &sa_quit, NULL); sigaction(SIGINT, &sa_quit, NULL); - atexit(&quit); } void usage(const char *name) @@ -118,11 +117,13 @@ void usage(const char *name) printf("Simulator2Simulator Server %s (built on %s, %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); - exit(EXIT_FAILURE); + die(); } int main(int argc, char *argv[]) { + _mtid = pthread_self(); + /* Check arguments */ #ifdef ENABLE_OPAL_ASYNC if (argc != 2 && argc != 4) @@ -130,8 +131,7 @@ int main(int argc, char *argv[]) if (argc != 2) #endif usage(argv[0]); - - epoch_reset(); + info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s, debug=%d)", BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__)), _debug); @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) else pause(); - /* Note: quit() is called by exit handler! */ + quit(); return 0; } diff --git a/server/src/utils.c b/server/src/utils.c index 4abf4d686..c0515cccf 100644 --- a/server/src/utils.c +++ b/server/src/utils.c @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #ifdef ENABLE_OPAL_ASYNC #define RTLAB @@ -24,20 +24,11 @@ #include "cfg.h" #include "utils.h" -/* This global variable contains the debug level for debug() and assert() macros */ -int _debug = V; -int _indent = 0; +pthread_t _mtid; -struct timespec epoch; - -void outdent(int *old) +void die() { - _indent = *old; -} - -void epoch_reset() -{ - clock_gettime(CLOCK_REALTIME, &epoch); + pthread_kill(_mtid, SIGTERM); } int strap(char *dest, size_t size, const char *fmt, ...) @@ -59,42 +50,6 @@ int vstrap(char *dest, size_t size, const char *fmt, va_list ap) return vsnprintf(dest + len, size - len, fmt, ap); } -void print(enum log_level lvl, const char *fmt, ...) -{ - struct timespec ts; - char buf[512] = ""; - - va_list ap; - - /* Timestamp */ - clock_gettime(CLOCK_REALTIME, &ts); - strap(buf, sizeof(buf), "%8.3f ", timespec_delta(&epoch, &ts)); - - /* Severity */ - switch (lvl) { - case DEBUG: strap(buf, sizeof(buf), BLD("%-5s "), GRY("Debug")); break; - case INFO: strap(buf, sizeof(buf), BLD("%-5s "), " " ); break; - case WARN: strap(buf, sizeof(buf), BLD("%-5s "), YEL(" Warn")); break; - case ERROR: strap(buf, sizeof(buf), BLD("%-5s "), RED("Error")); break; - } - - /* Indention */ - for (int i = 0; i < _indent; i++) - strap(buf, sizeof(buf), GFX("\x78") " "); - strap(buf, sizeof(buf), GFX("\x74") " "); - - /* Format String */ - va_start(ap, fmt); - vstrap(buf, sizeof(buf), fmt, ap); - va_end(ap); - - /* Output */ -#ifdef ENABLE_OPAL_ASYNC - OpalPrint("S2SS: %s\n", buf); -#endif - fprintf(stderr, "%s\n", buf); -} - cpu_set_t to_cpu_set(int set) { cpu_set_t cset; From 9cfdf4c87459fa8799dcd9bfcacfdc0f1fe18beb Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 18:03:55 +0100 Subject: [PATCH 24/29] small fixes and cleanups --- server/src/if.c | 2 +- server/src/opal.c | 6 +++--- server/src/random.c | 1 + server/src/server.c | 15 +++++---------- server/src/test.c | 4 ++-- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/server/src/if.c b/server/src/if.c index 64e7caf27..01eb104df 100644 --- a/server/src/if.c +++ b/server/src/if.c @@ -31,7 +31,7 @@ struct interface * if_create(int index) { i->index = index; if_indextoname(index, i->name); - debug(3, "Created interface '%s'", i->name, i->index, i->refcnt); + debug(3, "Created interface '%s' (index=%u)", i->name, i->index); list_init(&i->sockets, NULL); list_push(&interfaces, i); diff --git a/server/src/opal.c b/server/src/opal.c index f97e06c0c..b7783aa05 100644 --- a/server/src/opal.c +++ b/server/src/opal.c @@ -152,7 +152,7 @@ int opal_read(struct node *n, struct msg *m) if ((ret = OpalWaitForAsyncSendRequest(&id)) != EOK) { state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) { - info("OpalGetAsyncModelState(): Model stopped or resetted!"); + warn("OpalGetAsyncModelState(): Model stopped or resetted!"); die(); } @@ -194,7 +194,7 @@ int opal_read(struct node *n, struct msg *m) * has not been stopped. If it has, we quit. */ state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) { - info("OpalGetAsyncModelState(): Model stopped or resetted!"); + warn("OpalGetAsyncModelState(): Model stopped or resetted!"); die(); } @@ -212,7 +212,7 @@ int opal_write(struct node *n, struct msg *m) state = OpalGetAsyncModelState(); if ((state == STATE_RESET) || (state == STATE_STOP)) { - info("OpalGetAsyncModelState(): Model stopped or resetted!"); + warn("OpalGetAsyncModelState(): Model stopped or resetted!"); die(); } diff --git a/server/src/random.c b/server/src/random.c index 9350e4f2d..e169e4983 100644 --- a/server/src/random.c +++ b/server/src/random.c @@ -40,6 +40,7 @@ int main(int argc, char *argv[]) printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n"); printf(" Steffen Vogel \n"); + exit(EXIT_FAILURE); } diff --git a/server/src/server.c b/server/src/server.c index f352f4b86..5da2a3167 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -34,8 +34,8 @@ extern struct list paths; extern struct list interfaces; /** The global configuration */ -struct settings settings; -config_t config; +static struct settings settings; +static config_t config; static void quit() { @@ -61,18 +61,13 @@ static void quit() list_destroy(&interfaces); config_destroy(&config); + info("Goodbye!"); + _exit(EXIT_SUCCESS); } void realtime_init() { INDENT - /* Check for realtime kernel patch */ - struct stat st; - if (stat("/sys/kernel/realtime", &st)) - warn("Use a RT-preempt patched Linux for lower latencies!"); - else - info("Server is running on a realtime patched kernel"); - /* Use FIFO scheduler with real time priority */ if (settings.priority) { struct sched_param param = { .sched_priority = settings.priority }; @@ -144,7 +139,7 @@ int main(int argc, char *argv[]) list_init(&paths, (dtor_cb_t) path_destroy); list_init(&interfaces, (dtor_cb_t) if_destroy); - /* Start initialization */ + info("Initialize realtime system:"); realtime_init(); diff --git a/server/src/test.c b/server/src/test.c index 18768f6b7..6a8fbb6e1 100644 --- a/server/src/test.c +++ b/server/src/test.c @@ -122,9 +122,9 @@ int main(int argc, char *argv[]) error("Unknown option '-%c'.", optopt); else error("Unknown option character '\\x%x'.", optopt); - exit(1); + exit(EXIT_FAILURE); default: - abort (); + abort(); } continue; From 8587184bf6d6c42e1427786f4623754667244b80 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 18:04:52 +0100 Subject: [PATCH 25/29] added storage for previous message (this will may be extended to a variable number of past messages) --- server/src/path.c | 64 ++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/server/src/path.c b/server/src/path.c index 1db24ee0a..c08810433 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -56,13 +56,10 @@ static void * path_send(void *arg) while (1) { sigwait(&set, &sig); /* blocking wait for next timer tick */ - if (p->received) { - FOREACH(&p->destinations, it) { - node_write(it->node, p->last); - } - - p->sent++; - } + FOREACH(&p->destinations, it) + node_write(it->node, p->current); + + p->sent++; } return NULL; @@ -71,41 +68,48 @@ static void * path_send(void *arg) /** Receive messages */ static void * path_run(void *arg) { - char buf[33]; struct path *p = arg; - struct msg *m = alloc(sizeof(struct msg)); + + p->previous = alloc(sizeof(struct msg)); + p->current = alloc(sizeof(struct msg)); + char buf[33]; + /* Open deferred TCP connection */ node_start_defer(p->in); // FIXME: node_start_defer(p->out); + /* Main thread loop */ while (1) { - node_read(p->in, m); /* Receive message */ + node_read(p->in, p->current); /* Receive message */ p->received++; /* Check header fields */ - if (m->version != MSG_VERSION || - m->type != MSG_TYPE_DATA) { + if (p->current->version != MSG_VERSION || + p->current->type != MSG_TYPE_DATA) { p->invalid++; continue; } /* Update histogram */ - int dist = (UINT16_MAX + m->sequence - p->sequence) % UINT16_MAX; + int dist = (UINT16_MAX + p->current->sequence - p->previous->sequence) % UINT16_MAX; if (dist > UINT16_MAX / 2) dist -= UINT16_MAX; hist_put(&p->histogram, dist); /* Handle simulation restart */ - if (m->sequence == 0 && abs(dist) >= 1) { - path_print(p, buf, sizeof(buf)); - path_stats(p); - - warn("Simulation for path %s restarted (p->seq=%u, m->seq=%u, dist=%d)", - buf, p->sequence, m->sequence, dist); + if (p->current->sequence == 0 && abs(dist) >= 1) { + if (p->received) { + path_print_stats(p); + hist_print(&p->histogram); + } + + path_print(p, buf, sizeof(buf)); + warn("Simulation for path %s restarted (prev->seq=%u, current->seq=%u, dist=%d)", + buf, p->previous->sequence, p->current->sequence, dist); /* Reset counters */ p->sent = 0; @@ -114,7 +118,6 @@ static void * path_run(void *arg) p->skipped = 0; p->dropped = 0; - hist_print(&p->histogram); hist_reset(&p->histogram); } else if (dist <= 0 && p->received > 1) { @@ -124,27 +127,22 @@ static void * path_run(void *arg) /* Call hook callbacks */ FOREACH(&p->hooks, it) { - if (it->hook(m, p)) { + if (it->hook(p->current, p)) { p->skipped++; continue; } } - /* Update last known sequence number */ - p->sequence = m->sequence; - p->last = m; - /* At fixed rate mode, messages are send by another thread */ if (!p->rate) { - FOREACH(&p->destinations, it) { - node_write(it->node, m); - } - + FOREACH(&p->destinations, it) + node_write(it->node, p->current); + p->sent++; } - } - free(m); + SWAP(p->previous, p->current); + } return NULL; } @@ -180,10 +178,8 @@ int path_stop(struct path *p) timer_delete(p->timer); } - if (p->sent || p->received) { - path_print_stats(p); + if (p->received) hist_print(&p->histogram); - } return 0; } From 81f0465b1b406cecc3b1ee37a64c069e89871e21 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 18:16:03 +0100 Subject: [PATCH 26/29] chosed diffrent termination signal --- server/src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/utils.c b/server/src/utils.c index c0515cccf..d30dd2503 100644 --- a/server/src/utils.c +++ b/server/src/utils.c @@ -28,7 +28,7 @@ pthread_t _mtid; void die() { - pthread_kill(_mtid, SIGTERM); + pthread_kill(_mtid, SIGINT); } int strap(char *dest, size_t size, const char *fmt, ...) From 3ab5b1e6162123190f30ea2a87ca019563f0b180 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sat, 21 Mar 2015 18:16:28 +0100 Subject: [PATCH 27/29] updated year and format of usage output --- server/src/random.c | 8 +++++--- server/src/receive.c | 9 ++++++--- server/src/send.c | 8 +++++--- server/src/server.c | 9 ++++++--- server/src/test.c | 6 ++++-- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/server/src/random.c b/server/src/random.c index e169e4983..4d08c0844 100644 --- a/server/src/random.c +++ b/server/src/random.c @@ -37,9 +37,11 @@ int main(int argc, char *argv[]) printf("Usage: %s VALUES RATE\n", argv[0]); printf(" VALUES is the number of values a message contains\n"); printf(" RATE how many messages per second\n\n"); - printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); - printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n"); - printf(" Steffen Vogel \n"); + + printf("Simulator2Simulator Server %s (built on %s %s)\n", + BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); + printf(" Copyright 2015, Institute for Automation of Complex Power Systems, EONERC\n"); + printf(" Steffen Vogel \n"); exit(EXIT_FAILURE); } diff --git a/server/src/receive.c b/server/src/receive.c index bce4cb900..378311073 100644 --- a/server/src/receive.c +++ b/server/src/receive.c @@ -35,13 +35,16 @@ void quit(int sig, siginfo_t *si, void *ptr) void usage(char *name) { - printf("Usage: %s CONFIG NODE\n", name); + printf("Usage: %s [-r] CONFIG NODE\n", name); + printf(" -r swap local / remote address of socket based nodes)\n\n"); printf(" CONFIG path to a configuration file\n"); printf(" NODE name of the node which shoud be used\n\n"); + printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); - printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n"); - printf(" Steffen Vogel \n"); + printf(" Copyright 2015, Institute for Automation of Complex Power Systems, EONERC\n"); + printf(" Steffen Vogel \n"); + exit(EXIT_FAILURE); } diff --git a/server/src/send.c b/server/src/send.c index a9897bb62..a4f841e7a 100644 --- a/server/src/send.c +++ b/server/src/send.c @@ -38,13 +38,15 @@ void quit(int sig, siginfo_t *si, void *ptr) void usage(char *name) { printf("Usage: %s [-r] CONFIG NODE\n", name); - printf(" -r swap local / remote address of socket based nodes)\n"); + printf(" -r swap local / remote address of socket based nodes)\n\n"); printf(" CONFIG path to a configuration file\n"); printf(" NODE name of the node which shoud be used\n"); + printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); - printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n"); - printf(" Steffen Vogel \n"); + printf(" Copyright 2015, Institute for Automation of Complex Power Systems, EONERC\n"); + printf(" Steffen Vogel \n"); + exit(EXIT_FAILURE); } diff --git a/server/src/server.c b/server/src/server.c index 5da2a3167..ccd1e1018 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -96,6 +96,7 @@ void signals_init() }; sigemptyset(&sa_quit.sa_mask); + sigaction(SIGQUIT, &sa_quit, NULL); sigaction(SIGTERM, &sa_quit, NULL); sigaction(SIGINT, &sa_quit, NULL); } @@ -109,10 +110,12 @@ void usage(const char *name) printf(" This type of invocation is used by OPAL-RT Asynchronous processes.\n"); printf(" See in the RT-LAB User Guide for more information.\n\n"); #endif - printf("Simulator2Simulator Server %s (built on %s, %s)\n", + printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); - - die(); + printf(" Copyright 2015, Institute for Automation of Complex Power Systems, EONERC\n"); + printf(" Steffen Vogel \n"); + + exit(EXIT_FAILURE); } int main(int argc, char *argv[]) diff --git a/server/src/test.c b/server/src/test.c index 6a8fbb6e1..2deec58bf 100644 --- a/server/src/test.c +++ b/server/src/test.c @@ -67,10 +67,12 @@ int main(int argc, char *argv[]) printf(" CONFIG path to a configuration file\n"); printf(" TEST the name of the test to execute: 'rtt'\n"); printf(" NODE name of the node which shoud be used\n\n"); + printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__)); - printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n"); - printf(" Steffen Vogel \n"); + printf(" Copyright 2015, Institute for Automation of Complex Power Systems, EONERC\n"); + printf(" Steffen Vogel \n"); + exit(EXIT_FAILURE); } From 24dfcbfac9efd8288f872a50afbd660a0ab57afa Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 23 Mar 2015 17:54:37 +0100 Subject: [PATCH 28/29] added small script do automatically updte Doxygen documentation --- contrib/update_docs.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 contrib/update_docs.sh diff --git a/contrib/update_docs.sh b/contrib/update_docs.sh new file mode 100755 index 000000000..f517e1e5b --- /dev/null +++ b/contrib/update_docs.sh @@ -0,0 +1,12 @@ +#/bin/bash + +cd $( cd "$( dirname "$0" )/.." && pwd ) + +LASTREV=$(git rev-parse HEAD) +git pull --all +NEWREV=$(git rev-parse HEAD) + +if [ "$LASTREV" != "$NEWREV" ]; then + echo "There's a new version. Running doxygen" + doxygen +fi From 3590ced68e65c88e3db2c20b73f5605fbcb37003 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 23 Mar 2015 17:32:56 +0100 Subject: [PATCH 29/29] added copyright headers --- server/include/log.h | 9 ++++++++- server/src/log.c | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/server/include/log.h b/server/include/log.h index 5baf35b13..ecde7b582 100644 --- a/server/include/log.h +++ b/server/include/log.h @@ -1,4 +1,11 @@ -#ifndef _LOG_H_ +/** Logging and debugging routines + * + * @author Steffen Vogel + * @copyright 2015, Institute for Automation of Complex Power Systems, EONERC + * @file + */ + + #ifndef _LOG_H_ #define _LOG_H_ #ifdef __GNUC__ diff --git a/server/src/log.c b/server/src/log.c index c41c858d3..61a30abee 100644 --- a/server/src/log.c +++ b/server/src/log.c @@ -1,4 +1,10 @@ -#include +/** Logging and debugging routines + * + * @author Steffen Vogel + * @copyright 2015, Institute for Automation of Complex Power Systems, EONERC + */ + + #include #include #include "log.h"