Changeset View
Standalone View
tests/sys/kern/basic_signal.c
- This file was added.
/*- | |||||
* Copyright (c) 2021 Warner Losh <imp@bsdimp.com> | |||||
* | |||||
* SPDX-License-Identifier: BSD-2-Clause | |||||
*/ | |||||
kevans: Nice | |||||
#include <atf-c.h> | |||||
#include <errno.h> | |||||
#include <signal.h> | |||||
#include <stdbool.h> | |||||
#include <stdlib.h> | |||||
static volatile sig_atomic_t signal_fired = 0; | |||||
Done Inline Actions+volatile here and on the ARM ones kevans: +`volatile` here and on the ARM ones | |||||
static void | |||||
sig_handler(int signo, siginfo_t *info __unused, void *ucp __unused) | |||||
{ | |||||
signal_fired++; | |||||
} | |||||
ATF_TC(signal_test); | |||||
ATF_TC_HEAD(signal_test, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal"); | |||||
} | |||||
ATF_TC_BODY(signal_test, tc) | |||||
{ | |||||
/* | |||||
* Setup the signal handlers | |||||
*/ | |||||
struct sigaction sa = { | |||||
.sa_sigaction = sig_handler, | |||||
.sa_flags = SA_SIGINFO, | |||||
}; | |||||
ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); | |||||
ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); | |||||
ATF_REQUIRE(sigaction(SIGUSR2, &sa, NULL) == 0); | |||||
ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0); | |||||
/* | |||||
* Fire SIGUSR1 | |||||
*/ | |||||
ATF_CHECK(signal_fired == 0); | |||||
ATF_REQUIRE(raise(SIGUSR1) == 0); | |||||
ATF_CHECK(signal_fired == 1); | |||||
/* | |||||
* Fire SIGUSR2 | |||||
*/ | |||||
ATF_REQUIRE(raise(SIGUSR2) == 0); | |||||
ATF_CHECK(signal_fired == 2); | |||||
/* | |||||
* Fire SIGALRM after a timeout | |||||
*/ | |||||
ATF_REQUIRE(alarm(1) == 0); | |||||
ATF_REQUIRE(pause() == -1); | |||||
ATF_REQUIRE(errno == EINTR); | |||||
ATF_CHECK(signal_fired == 3); | |||||
} | |||||
/* | |||||
* Special tests for 32-bit arm. We can call thumb (really just t32) from normal | |||||
* (a32) mode and vice versa. Likewise, signals can interrupt a T32 context with | |||||
* A32 code and vice versa. Make sure these all work with a simple test that | |||||
* raises the signal and ensures that it executed. No other platform has these | |||||
* requirements. Also note: we only support thumb2, so there's no T16 vs T32 | |||||
* issues we have to test for. | |||||
*/ | |||||
#ifdef __arm__ | |||||
/* | |||||
* Sadly, there's no standard for these things. | |||||
*/ | |||||
#ifdef __clang__ | |||||
#define a32_isa __attribute__((target("no-thumb-mode"))) | |||||
Done Inline ActionsI think this and the below will need alternative GCC versions; the GCC documentation seems to indicate that arch= is specifically for -march options, and the GCC equivalents to this specifically are just target("arm") and target("thumb"). I wonder if these are worth macros in cdefs.h, but I really can't come up with a good name for those... __thumb is maybe not terrible, but __arm probably is. __a32 and __t32 maybe, but that feels a bit obscure. kevans: I think this and the below will need alternative GCC versions; the GCC documentation seems to… | |||||
Done Inline ActionsI think clang now support the GNU syntax, so maybe using it would be enough ? cognet: I think clang now support the GNU syntax, so maybe using it would be enough ?
https://reviews. | |||||
Done Inline ActionsThey build and appear to work on both. I'm not sure I want to invent something for FreeBSD for an architecture that may be the long glide path after peaking that currently only has use in a test. imp: They build and appear to work on both. I'm not sure I want to invent something for FreeBSD for… | |||||
Done Inline ActionsHmmm, there may be a clang issue... Rebuilding to make sure. imp: Hmmm, there may be a clang issue... Rebuilding to make sure.
| |||||
Done Inline ActionsAs you see, I needed to update since the above code review doesn't seem to be in the clang tree yet. Or at least the latest tree needs them... imp: As you see, I needed to update since the above code review doesn't seem to be in the clang tree… | |||||
Done Inline ActionsMy last comment is wrong: this code was wrong in arch=arm. target(arm) and target(thumb) just work for both gcc and clang. imp: My last comment is wrong: this code was wrong in arch=arm. target(arm) and target(thumb) just… | |||||
#define t32_isa __attribute__((target("thumb-mode"))) | |||||
#else | |||||
#define a32_isa __attribute__((target("arch=arm"))) | |||||
cognetUnsubmitted Not Done Inline ActionsShouldn't that be just target("arm") and target("thumb") for gcc ? :) cognet: Shouldn't that be just target("arm") and target("thumb") for gcc ? :) | |||||
#define t32_isa __attribute__((target("arch=thumb"))) | |||||
#endif | |||||
static volatile sig_atomic_t t32_fired = 0; | |||||
static volatile sig_atomic_t a32_fired = 0; | |||||
a32_isa | |||||
static void | |||||
sig_a32(int signo, siginfo_t *info __unused, void *ucp __unused) | |||||
{ | |||||
a32_fired++; | |||||
} | |||||
t32_isa | |||||
static void | |||||
sig_t32(int signo, siginfo_t *info __unused, void *ucp __unused) | |||||
{ | |||||
t32_fired++; | |||||
} | |||||
ATF_TC(signal_test_T32_to_A32); | |||||
ATF_TC_HEAD(signal_test_T32_to_A32, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from T32 to A32"); | |||||
} | |||||
t32_isa | |||||
ATF_TC_BODY(signal_test_T32_to_A32, tc) | |||||
{ | |||||
/* | |||||
* Setup the signal handlers | |||||
*/ | |||||
struct sigaction sa = { | |||||
.sa_sigaction = sig_a32, | |||||
.sa_flags = SA_SIGINFO, | |||||
}; | |||||
ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); | |||||
ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); | |||||
ATF_REQUIRE((((uintptr_t)sig_a32) & 1) == 0); | |||||
ATF_CHECK(a32_fired == 0); | |||||
ATF_REQUIRE(raise(SIGUSR1) == 0); | |||||
ATF_CHECK(a32_fired == 1); | |||||
} | |||||
ATF_TC(signal_test_A32_to_T32); | |||||
ATF_TC_HEAD(signal_test_A32_to_T32, tc) | |||||
{ | |||||
atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from A32 to T32"); | |||||
} | |||||
a32_isa | |||||
ATF_TC_BODY(signal_test_A32_to_T32, tc) | |||||
{ | |||||
/* | |||||
* Setup the signal handlers | |||||
*/ | |||||
struct sigaction sa = { | |||||
.sa_sigaction = sig_t32, | |||||
.sa_flags = SA_SIGINFO, | |||||
}; | |||||
ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); | |||||
ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); | |||||
ATF_REQUIRE((((uintptr_t)sig_t32) & 1) == 1); | |||||
ATF_CHECK(t32_fired == 0); | |||||
ATF_REQUIRE(raise(SIGUSR1) == 0); | |||||
ATF_CHECK(t32_fired == 1); | |||||
} | |||||
#endif | |||||
ATF_TP_ADD_TCS(tp) | |||||
{ | |||||
ATF_TP_ADD_TC(tp, signal_test); | |||||
#ifdef __arm__ | |||||
ATF_TP_ADD_TC(tp, signal_test_T32_to_A32); | |||||
ATF_TP_ADD_TC(tp, signal_test_A32_to_T32); | |||||
#endif | |||||
return (atf_no_error()); | |||||
} |
Nice