From: "Alex Bennée" <alex.bennee@linaro.org>
To: peter.maydell@linaro.org
Cc: "Richard Henderson" <richard.henderson@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
qemu-devel@nongnu.org
Subject: [PULL 1/8] tests/tcg: add a multiarch signals test to stress test signal delivery
Date: Mon, 7 Jun 2021 15:32:56 +0100 [thread overview]
Message-ID: <20210607143303.28572-2-alex.bennee@linaro.org> (raw)
In-Reply-To: <20210607143303.28572-1-alex.bennee@linaro.org>
This adds a simple signal test that combines the POSIX timer_create
with signal delivery across multiple threads. The aim is to provide a
bit more of a stress test to flush out signal handling issues for
easily than the occasional random crash we sometimes see in linux-test
or threadcount.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210527160319.19834-2-alex.bennee@linaro.org>
diff --git a/tests/tcg/multiarch/signals.c b/tests/tcg/multiarch/signals.c
new file mode 100644
index 0000000000..998c8fdefd
--- /dev/null
+++ b/tests/tcg/multiarch/signals.c
@@ -0,0 +1,149 @@
+/*
+ * linux-user signal handling tests.
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <string.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+
+static void error1(const char *filename, int line, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: ", filename, line);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(1);
+}
+
+static int __chk_error(const char *filename, int line, int ret)
+{
+ if (ret < 0) {
+ error1(filename, line, "%m (ret=%d, errno=%d/%s)",
+ ret, errno, strerror(errno));
+ }
+ return ret;
+}
+
+#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
+
+#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
+
+/*
+ * Thread handling
+ */
+typedef struct ThreadJob ThreadJob;
+
+struct ThreadJob {
+ int number;
+ int sleep;
+ int count;
+};
+
+static pthread_t *threads;
+static int max_threads = 10;
+__thread int signal_count;
+int total_signal_count;
+
+static void *background_thread_func(void *arg)
+{
+ ThreadJob *job = (ThreadJob *) arg;
+
+ printf("thread%d: started\n", job->number);
+ while (total_signal_count < job->count) {
+ usleep(job->sleep);
+ }
+ printf("thread%d: saw %d alarms from %d\n", job->number,
+ signal_count, total_signal_count);
+ return NULL;
+}
+
+static void spawn_threads(void)
+{
+ int i;
+ threads = calloc(sizeof(pthread_t), max_threads);
+
+ for (i = 0; i < max_threads; i++) {
+ ThreadJob *job = calloc(sizeof(ThreadJob), 1);
+ job->number = i;
+ job->sleep = i * 1000;
+ job->count = i * 100;
+ pthread_create(threads + i, NULL, background_thread_func, job);
+ }
+}
+
+static void close_threads(void)
+{
+ int i;
+ for (i = 0; i < max_threads; i++) {
+ pthread_join(threads[i], NULL);
+ }
+ free(threads);
+ threads = NULL;
+}
+
+static void sig_alarm(int sig, siginfo_t *info, void *puc)
+{
+ if (sig != SIGRTMIN) {
+ error("unexpected signal");
+ }
+ signal_count++;
+ __atomic_fetch_add(&total_signal_count, 1, __ATOMIC_SEQ_CST);
+}
+
+static void test_signals(void)
+{
+ struct sigaction act;
+ struct itimerspec it;
+ timer_t tid;
+ struct sigevent sev;
+
+ /* Set up SIG handler */
+ act.sa_sigaction = sig_alarm;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+ chk_error(sigaction(SIGRTMIN, &act, NULL));
+
+ /* Create POSIX timer */
+ sev.sigev_notify = SIGEV_SIGNAL;
+ sev.sigev_signo = SIGRTMIN;
+ sev.sigev_value.sival_ptr = &tid;
+ chk_error(timer_create(CLOCK_REALTIME, &sev, &tid));
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_nsec = 1000000;
+ it.it_value.tv_sec = 0;
+ it.it_value.tv_nsec = 1000000;
+ chk_error(timer_settime(tid, 0, &it, NULL));
+
+ spawn_threads();
+
+ do {
+ usleep(1000);
+ } while (total_signal_count < 2000);
+
+ printf("shutting down after: %d signals\n", total_signal_count);
+
+ close_threads();
+
+ chk_error(timer_delete(tid));
+}
+
+int main(int argc, char **argv)
+{
+ test_signals();
+ return 0;
+}
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index a3a751723d..3f283eabe6 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -30,6 +30,8 @@ testthread: LDFLAGS+=-lpthread
threadcount: LDFLAGS+=-lpthread
+signals: LDFLAGS+=-lrt -lpthread
+
# We define the runner for test-mmap after the individual
# architectures have defined their supported pages sizes. If no
# additional page sizes are defined we only run the default test.
--
2.20.1
next prev parent reply other threads:[~2021-06-07 14:34 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-07 14:32 [PULL 0/8] testing and misc updates Alex Bennée
2021-06-07 14:32 ` Alex Bennée [this message]
2021-06-07 14:32 ` [PULL 2/8] meson.build: fix cosmetics of compiler display Alex Bennée
2021-06-07 14:32 ` [PULL 3/8] tests/tcg/configure.sh: tweak quoting of target_compiler Alex Bennée
2021-06-07 14:32 ` [PULL 4/8] tests/acceptance: tag various arm tests as TCG only Alex Bennée
2021-06-07 14:33 ` [PULL 5/8] gitlab: work harder to avoid false positives in checkpatch Alex Bennée
2021-06-07 14:50 ` Daniel P. Berrangé
2021-06-07 16:14 ` Alex Bennée
2021-06-07 16:19 ` Daniel P. Berrangé
2021-06-07 14:33 ` [PULL 6/8] gitlab-ci: Split gprof-gcov job Alex Bennée
2021-06-07 14:33 ` [PULL 7/8] tests/vm: expose --source-path to scripts to find extra files Alex Bennée
2021-06-07 14:33 ` [PULL 8/8] scripts/checkpatch.pl: process .c.inc and .h.inc files as C source Alex Bennée
2021-06-07 16:17 ` [PULL 0/8] testing and misc updates Peter Maydell
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=20210607143303.28572-2-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/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).