xenomai.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Johannes Kirchmair <johannes.kirchmair@sigmatek.at>
To: xenomai@lists.linux.dev
Cc: Johannes Kirchmair <johannes.kirchmair@sigmatek.at>
Subject: [PATCH 3/3] [POC] add a tool to measure rt_signal latency
Date: Fri,  8 Sep 2023 12:50:43 +0200	[thread overview]
Message-ID: <20230908105043.1355310-3-johannes.kirchmair@sigmatek.at> (raw)
In-Reply-To: <20230908105043.1355310-1-johannes.kirchmair@sigmatek.at>

Signed-off-by: Johannes Kirchmair <johannes.kirchmair@sigmatek.at>
---
 configure.ac                          |   1 +
 utils/Makefile.am                     |   2 +-
 utils/rt_signal_hist/Makefile.am      |  22 ++++
 utils/rt_signal_hist/error.h          |  14 +++
 utils/rt_signal_hist/histo.c          |  46 ++++++++
 utils/rt_signal_hist/histo.h          |  13 +++
 utils/rt_signal_hist/result.c         |  16 +++
 utils/rt_signal_hist/result.h         |  12 ++
 utils/rt_signal_hist/rt_signal_hist.c | 158 ++++++++++++++++++++++++++
 9 files changed, 283 insertions(+), 1 deletion(-)
 create mode 100644 utils/rt_signal_hist/Makefile.am
 create mode 100644 utils/rt_signal_hist/error.h
 create mode 100644 utils/rt_signal_hist/histo.c
 create mode 100644 utils/rt_signal_hist/histo.h
 create mode 100644 utils/rt_signal_hist/result.c
 create mode 100644 utils/rt_signal_hist/result.h
 create mode 100644 utils/rt_signal_hist/rt_signal_hist.c

diff --git a/configure.ac b/configure.ac
index 3325482fc..fe4a3b3e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1054,6 +1054,7 @@ AC_CONFIG_FILES([ \
 	utils/slackspot/Makefile \
 	utils/corectl/Makefile \
 	utils/autotune/Makefile \
+	utils/rt_signal_hist/Makefile \
 	utils/net/rtnet \
 	utils/net/rtnet.conf \
 	utils/net/Makefile \
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 4de6434a9..79c39ac90 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -1,5 +1,5 @@
 SUBDIRS = hdb
 if XENO_COBALT
-SUBDIRS += analogy autotune can net ps slackspot corectl
+SUBDIRS += analogy autotune can net ps slackspot corectl rt_signal_hist
 endif
 SUBDIRS += chkkconf
diff --git a/utils/rt_signal_hist/Makefile.am b/utils/rt_signal_hist/Makefile.am
new file mode 100644
index 000000000..810a63bba
--- /dev/null
+++ b/utils/rt_signal_hist/Makefile.am
@@ -0,0 +1,22 @@
+testdir = @XENO_TEST_DIR@
+
+CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC)
+
+test_PROGRAMS = rt_signal_hist
+
+alchemycppflags =              			 \
+	$(XENO_USER_CFLAGS)    			 \
+	-I$(top_srcdir)/include
+
+alchemyldadd =					\
+	@XENO_AUTOINIT_LDFLAGS@			\
+	$(XENO_POSIX_WRAPPERS)			\
+	../../lib/alchemy/libalchemy.la		\
+	../../lib/copperplate/libcopperplate.la	\
+	@XENO_CORE_LDADD@			\
+	@XENO_USER_LDADD@			\
+	-lrt -lpthread -lm
+
+rt_signal_hist_SOURCES = rt_signal_hist.c histo.c result.c
+rt_signal_hist_CPPFLAGS = $(alchemycppflags)
+rt_signal_hist_LDADD = $(alchemyldadd)
diff --git a/utils/rt_signal_hist/error.h b/utils/rt_signal_hist/error.h
new file mode 100644
index 000000000..4aa50e70e
--- /dev/null
+++ b/utils/rt_signal_hist/error.h
@@ -0,0 +1,14 @@
+#ifndef ERROR_EXIT_H
+#define ERROR_EXIT_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static int error(char *reason, int ret)
+{
+	printf("%s: err= %d\n", reason, ret);
+	exit(1);
+}
+
+#endif
+
diff --git a/utils/rt_signal_hist/histo.c b/utils/rt_signal_hist/histo.c
new file mode 100644
index 000000000..36e51201b
--- /dev/null
+++ b/utils/rt_signal_hist/histo.c
@@ -0,0 +1,46 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "histo.h"
+#include "error.h"
+
+void initHisto(struct histo **histo, unsigned long n)
+{
+	int i = 0;
+	*histo = malloc(sizeof(struct histo) + n * sizeof(unsigned long));
+	if (!histo)
+		return;
+
+	for (i = 0; i < n; ++i) {
+		(*histo)->data[i] = 0;
+	}
+	(*histo)->max_index = 0;
+	(*histo)->n = n;
+}
+
+void writeHisto(struct histo *histo)
+{
+	unsigned long i;
+	FILE *f = fopen("hist.txt", "w");
+	if (!f)
+		error("can't open \"hist.txt\n", errno);
+
+	for (i = 0; i <= histo->max_index; ++i) {
+		fprintf(f, "%lu %lu\n", i, histo->data[i]);
+	}
+
+	fclose(f);
+}
+
+void updateHisto(struct histo *histo, unsigned long curr)
+{
+	unsigned long index;
+
+	index = curr;
+	index = index >= histo->n ? histo->n - 1 : index;
+
+	histo->max_index = histo->max_index >= index ? histo->max_index : index;
+	histo->data[index]++;
+}
+
diff --git a/utils/rt_signal_hist/histo.h b/utils/rt_signal_hist/histo.h
new file mode 100644
index 000000000..63c92014a
--- /dev/null
+++ b/utils/rt_signal_hist/histo.h
@@ -0,0 +1,13 @@
+#ifndef HISTO_H
+#define HISTO_H
+
+struct histo {
+	unsigned long n;
+	unsigned long max_index;
+	unsigned long data[];
+};
+
+void initHisto(struct histo **histo, unsigned long n);
+void writeHisto(struct histo *histo);
+void updateHisto(struct histo *histo, unsigned long curr);
+#endif
diff --git a/utils/rt_signal_hist/result.c b/utils/rt_signal_hist/result.c
new file mode 100644
index 000000000..a863d7182
--- /dev/null
+++ b/utils/rt_signal_hist/result.c
@@ -0,0 +1,16 @@
+#include "result.h"
+
+void initResult(struct result *resu)
+{
+	resu->min = (unsigned long)-1l;
+	resu->max = 0ul;
+	resu->avr = 0ul;
+}
+
+void updateResult(struct result *resu, unsigned long curr, unsigned long ith_entry)
+{
+	resu->min = curr < resu->min ? curr: resu->min;
+	resu->max = curr > resu->max ? curr: resu->max;
+	resu->avr = (resu->avr *(ith_entry - 1) + curr) / ith_entry;
+}
+
diff --git a/utils/rt_signal_hist/result.h b/utils/rt_signal_hist/result.h
new file mode 100644
index 000000000..9895535ee
--- /dev/null
+++ b/utils/rt_signal_hist/result.h
@@ -0,0 +1,12 @@
+#ifndef RESULT_H
+#define RESULT_H
+
+struct result {
+	unsigned long min;
+	unsigned long max;
+	unsigned long avr;
+};
+
+void initResult(struct result *resu);
+void updateResult(struct result *resu, unsigned long curr, unsigned long ith_entry);
+#endif
diff --git a/utils/rt_signal_hist/rt_signal_hist.c b/utils/rt_signal_hist/rt_signal_hist.c
new file mode 100644
index 000000000..076084e9e
--- /dev/null
+++ b/utils/rt_signal_hist/rt_signal_hist.c
@@ -0,0 +1,158 @@
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <asm/ucontext.h>
+
+#include <alchemy/task.h>
+#include <cobalt/signal.h>
+#include <copperplate/clockobj.h>
+
+#include "histo.h"
+#include "result.h"
+#include "error.h"
+
+#define TEST_SIGNAL SIGILL
+#define USE_GETTIME 0
+#define USE_RT_SIGNALS 1
+
+static RT_TASK task;
+
+static void do_cleanup(void *context)
+{
+	struct ucontext *uc = context;
+
+#if defined(__i386__)
+	uc->uc_mcontext.eip += 2;
+#elif defined(__x86_64__)
+	uc->uc_mcontext.rip += 2;
+#else
+	uc->uc_mcontext.pc += 4;
+#endif
+}
+
+static void sighandler(int sig, siginfo_t *info, void *data)
+{
+	do_cleanup(data);
+}
+
+static void do_ill(void)
+{
+#if defined(__i386__) || defined (__x86_64__)
+	__asm__("ud2");
+#else
+	__asm__("udf #0xdead");
+#endif
+}
+
+static void registerSignal(void)
+{
+	int ret;
+
+	ret = cobalt_rt_signal(TEST_SIGNAL, sighandler);
+	if (ret)
+		error("cobalt_rt_signal", ret);
+}
+
+static void printPreRunInfo(void)
+{
+	if (USE_GETTIME) {
+		struct timespec time;
+		clock_getres(CLOCK_MONOTONIC_RAW, &time);
+		printf("res_sec = %ld res_nsec = %ld \n", time.tv_sec, time.tv_nsec);
+	} else {
+		printf("res_nsec = %lld\n", clockobj_tsc_to_ns(1));
+	}
+}
+
+static inline unsigned long ns_now(void)
+{
+	if (USE_GETTIME) {
+		struct timespec time;
+		clock_gettime(CLOCK_MONOTONIC_RAW, &time);
+		return time.tv_nsec;
+	} else {
+		ticks_t ticks;
+		ticks = clockobj_get_tsc();
+		return clockobj_tsc_to_ns(ticks);
+	}
+}
+
+static void task_func(void *cookie)
+{
+	struct histo *histo = (struct histo *)cookie;
+	struct result resu;
+
+	unsigned long start, stop, curr;
+	int i, j;
+
+	printPreRunInfo();
+
+	registerSignal();
+
+	initResult(&resu);
+
+	for (j = 0; j < 10000; ++j) {
+		for (i = 0; i < 1000; ++i) {
+
+			start = ns_now();
+			do_ill();
+			stop = ns_now();
+
+			if (stop <= start) { // dismiss on counter overrun
+				continue;
+			}
+
+			curr = stop - start;
+
+			updateResult(&resu, curr, i+1); // + 1 as we add with index i the (i+1)th entry
+
+			updateHisto(histo, curr);
+		}
+
+		printf("min = %lu max = %lu avr = %lu\n", resu.min, resu.max, resu.avr);
+		rt_task_sleep(1000000);
+	}
+}
+
+static const char *task_name = "signal_test_task";
+static const int prio = 80;
+
+int main(int argc, char **argv)
+{
+	int ret;
+	struct histo *histo;
+
+	struct sigaction sa;
+
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_sigaction = sighandler;
+	sa.sa_flags = SA_SIGINFO | SA_NODEFER;
+	sigaction(TEST_SIGNAL, &sa, NULL);
+
+	initHisto(&histo, 100000000);
+	if (!histo)
+		error("could not init histo", -ENOMEM);
+
+	ret = rt_task_create(&task, task_name, 0, prio, T_JOINABLE);
+	if (ret)
+		error("rt_task_create", ret);
+
+	ret = rt_task_start(&task, task_func, histo);
+	if (ret)
+		error("cant start task", ret);
+
+	rt_task_join(&task);
+	rt_task_delete(&task);
+
+	writeHisto(histo);
+
+	return 0;
+}
+
-- 
2.25.1


  parent reply	other threads:[~2023-09-08 10:51 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-08 10:50 [PATCH 1/3] [POC] test implementaion of rt-signals Johannes Kirchmair
2023-09-08 10:50 ` [PATCH 2/3] [POC] Add rt_signal test Johannes Kirchmair
2023-09-08 10:50 ` Johannes Kirchmair [this message]
2023-09-08 10:54 ` [PATCH 1/3] [POC] test implementaion of rt-signals Johannes Kirchmair
2023-09-09 11:35 ` Jan Kiszka
  -- strict thread matches above, loose matches on Subject: below --
2023-08-16 10:18 Johannes Kirchmair
2023-08-16 10:18 ` [PATCH 3/3] [POC] add a tool to measure rt_signal latency Johannes Kirchmair
2023-05-09 13:13 [PATCH 1/3] [POC] test implementaion of rt-signals Johannes Kirchmair
2023-05-09 13:13 ` [PATCH 3/3] [POC] add a tool to measure rt_signal latency Johannes Kirchmair

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230908105043.1355310-3-johannes.kirchmair@sigmatek.at \
    --to=johannes.kirchmair@sigmatek.at \
    --cc=xenomai@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).