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
next prev 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).