Reputation: 309
This code is simulating interrupts in hardware. There are 2 threads. The main thread constructs a Hardware object and waits for Ctrl+C. The server thread handles web requests and calls the interrupt handler on command. Thread sanitizer reports a data race in function OnPostIrq
, but I cannot see that. enableInterrupt
is initialized to false before the thread is created, and is not modified since then. The code is compiled using gcc 14.1.1 in wsl.
// hardware.cpp
typedef void (*InterruptHandler)(void *);
struct Hardware { // simulation of hardware interrupt
std::atomic_bool enableInterrupt{}; // initialized to false before serverThread's constructor
InterruptHandler interruptHandler;
void *interruptHandlerArg;
Server server; // use a server so that simulation can be controlled by a web client
std::jthread serverThread;
Hardware()
: server{"http://127.0.0.1:9876", s_route}, // maps web requests to callbacks
serverThread{[](Server *server) {
PrintThreadId("Server Poll");
while (!HasStopCmd())
server->Poll(20);
},
&server} {
PrintThreadId("Hardware::Hardware");
}
bool CallInterruptHandler() {
bool enable = enableInterrupt;
if (enable) {
interruptHandler(interruptHandlerArg);
}
return enable;
}
};
static void OnPostIrq() { // called when the web client gives an irq command
PrintThreadId("Server OnPostIrq"); // same thread as Server Poll
g_hardware->CallInterruptHandler(); // thread sanitizer reports a data race, why
}
static std::unique_ptr<Hardware> g_hardware;
void Hardware_Create() {
assert(!g_hardware);
g_hardware = std::make_unique<Hardware>();
}
void Hardware_Destroy() {
assert(g_hardware);
g_hardware.reset();
}
// main.c
static _Atomic bool g_stopCmd;
bool HasStopCmd() { return g_stopCmd; }
static void SigHandler(int signo) {
if (signo == SIGINT) {
g_stopCmd = true;
}
}
int main() {
signal(SIGINT, SigHandler);
Hardware_Create();
while (!HasStopCmd()) {
SleepMs(10);
}
Hardware_Destroy();
}
Upvotes: 0
Views: 51