Jackoo
Jackoo

Reputation: 309

ThreadSanitizer reports data race on this code

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();
}

project code

Upvotes: 0

Views: 51

Answers (0)

Related Questions