unittests/FEXLinuxTests: Fixes race condition in signal_sra_state

This was using a one second alarm which could catch the JIT while it is
still busy. Instead wait for it to let an alarm thread that it is ready,
then tgkill the thread. This removes the race that this was hitting.
This commit is contained in:
Ryan Houdek committed 2026-08-24 19:02:39 -07:00
1 parent 22498dc871
commit 8d69852785
1 file changed
+17 -4
@@ -1,14 +1,16 @@
#include <catch2/catch_test_macros.hpp>
#include <atomic>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <thread>
#pragma GCC diagnostic ignored "-Wattributes"
constexpr static uint32_t xmm_values[8][4] = {
__attribute__((aligned(16))) constexpr static uint32_t xmm_values[8][4] = {
{0x00000001, 0x00000002, 0x00000003, 0x00000004}, {0x00000011, 0x00000012, 0x00000013, 0x00000014},
{0x00000021, 0x00000022, 0x00000023, 0x00000024}, {0x00000031, 0x00000032, 0x00000033, 0x00000034},
{0x00000041, 0x00000042, 0x00000043, 0x00000044}, {0x00000051, 0x00000052, 0x00000053, 0x00000054},
@@ -19,6 +21,8 @@ constexpr static uint32_t xmm_values[8][4] = {
static uint32_t results[4 + 32] __attribute__((aligned(16)));
static volatile int alarm_fired = 0;
static std::atomic<uint32_t> test_ready {};
extern "C" void ContinueAfterSignal();
static void SignalHandler(int signal, siginfo_t* siginfo, void* context) {
@@ -62,6 +66,7 @@ __attribute__((nocf_check)) static void LoadRegsLoopAndStore() {
movaps xmm6, [%[v]+96]
movaps xmm7, [%[v]+112]
mov %[test_ready], ecx
mov eax, %[alarm]
test eax, eax
jz .Lloop
@@ -79,11 +84,17 @@ __attribute__((nocf_check)) static void LoadRegsLoopAndStore() {
movaps [%[res]+96], xmm5
movaps [%[res]+112], xmm6
movaps [%[res]+128], xmm7
)" ::[v] "r"(xmm_values),
[alarm] "m"(alarm_fired), [res] "r"(results)
)" ::[v] "r"(&xmm_values),
[alarm] "m"(alarm_fired), [res] "r"(results), [test_ready] "m"(test_ready)
: "memory", "cc", "eax", "ecx", "edx");
}
static void AlarmThread(int thread_to_alarm) {
while (!test_ready.load())
;
tgkill(::getpid(), thread_to_alarm, SIGALRM);
}
TEST_CASE("Signals: Register state preserved across async signal with SRA") {
struct sigaction act {};
act.sa_sigaction = SignalHandler;
@@ -93,7 +104,7 @@ TEST_CASE("Signals: Register state preserved across async signal with SRA") {
alarm_fired = 0;
memset(results, 0, sizeof(results));
alarm(1);
std::thread t(AlarmThread, ::gettid());
LoadRegsLoopAndStore();
REQUIRE(alarm_fired == 1);
@@ -110,4 +121,6 @@ TEST_CASE("Signals: Register state preserved across async signal with SRA") {
CHECK(val == xmm_values[i][j]);
}
}
t.join();
}