From 68442f067484f2364904e3f6c3c4938e151a87de Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 24 Apr 2026 12:54:50 -0500 Subject: [PATCH] [core] Let defines.h pick the right thread model per platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit defines.h previously hardcoded ESPHOME_THREAD_MULTI_ATOMICS regardless of the active USE_, so the clang-tidy envs ended up compiling e.g. wake_esp8266.cpp with USE_ESP8266 + MULTI_ATOMICS both set — a combination that cannot occur in a real build and that mismatched the extern in wake.h. Pick the model that real codegen uses: USE_ESP8266 / USE_RP2040 / USE_NRF52 → SINGLE USE_BK72XX (ARMv5TE, no LDREX/STREX) → MULTI_NO_ATOMICS everything else (ESP32, host, RTL87XX, LN882X) → MULTI_ATOMICS With that, the single-only wake TUs (esp8266, rp2040, generic) can drop the defensive conditional and just define g_wake_requested as plain volatile again. --- esphome/core/defines.h | 15 ++++++++++++++- esphome/core/wake/wake_esp8266.cpp | 8 +------- esphome/core/wake/wake_generic.cpp | 12 ++---------- esphome/core/wake/wake_rp2040.cpp | 8 +------- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 80247f69da1..5a14c472311 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -17,8 +17,21 @@ #define ESPHOME_DEBUG_SCHEDULER #define ESPHOME_DEBUG_API -// Default threading model for static analysis (ESP32 is multi-threaded with atomics) +// Threading model for static analysis. Match what the real codegen picks per +// platform (see esphome/components//__init__.py ThreadModel.*): +// USE_ESP8266 / USE_RP2040 / USE_NRF52 → SINGLE +// USE_BK72XX (ARMv5TE, no LDREX/STREX) → MULTI_NO_ATOMICS +// everything else (ESP32, host, RTL87XX, LN882X) → MULTI_ATOMICS +// Without this the clang-tidy envs end up with USE_ +// + MULTI_ATOMICS simultaneously, a combination that can never occur in a +// real build. +#if defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_NRF52) +#define ESPHOME_THREAD_SINGLE +#elif defined(USE_BK72XX) +#define ESPHOME_THREAD_MULTI_NO_ATOMICS +#else #define ESPHOME_THREAD_MULTI_ATOMICS +#endif // logger #define ESPHOME_LOG_LEVEL ESPHOME_LOG_LEVEL_VERY_VERBOSE diff --git a/esphome/core/wake/wake_esp8266.cpp b/esphome/core/wake/wake_esp8266.cpp index 4c12470148f..9ced43c6dff 100644 --- a/esphome/core/wake/wake_esp8266.cpp +++ b/esphome/core/wake/wake_esp8266.cpp @@ -8,15 +8,9 @@ namespace esphome { // === Wake-requested flag + main-loop woke flag storage === -// ESP8266 is always ESPHOME_THREAD_SINGLE in real builds, but defines.h (used -// for static analysis / IDE) can define ESPHOME_THREAD_MULTI_ATOMICS alongside -// USE_ESP8266, so the storage type here has to match wake.h's conditional. +// ESP8266 is always ESPHOME_THREAD_SINGLE. // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) -#ifdef ESPHOME_THREAD_MULTI_ATOMICS -std::atomic g_wake_requested{0}; -#else volatile uint8_t g_wake_requested = 0; -#endif volatile bool g_main_loop_woke = false; // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) diff --git a/esphome/core/wake/wake_generic.cpp b/esphome/core/wake/wake_generic.cpp index b90aa593b3f..40044e43115 100644 --- a/esphome/core/wake/wake_generic.cpp +++ b/esphome/core/wake/wake_generic.cpp @@ -8,17 +8,9 @@ namespace esphome { // === Wake-requested flag storage === -// Fallback platforms (currently only Zephyr/NRF52) are ESPHOME_THREAD_SINGLE in -// real builds, but defines.h (used for static analysis / IDE) can define -// ESPHOME_THREAD_MULTI_ATOMICS here too, so the storage type has to match -// wake.h's conditional. -// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) -#ifdef ESPHOME_THREAD_MULTI_ATOMICS -std::atomic g_wake_requested{0}; -#else +// Fallback platforms (currently only Zephyr/NRF52) are ESPHOME_THREAD_SINGLE. +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) volatile uint8_t g_wake_requested = 0; -#endif -// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) } // namespace esphome diff --git a/esphome/core/wake/wake_rp2040.cpp b/esphome/core/wake/wake_rp2040.cpp index 3fa47d4dcca..b18248dbd27 100644 --- a/esphome/core/wake/wake_rp2040.cpp +++ b/esphome/core/wake/wake_rp2040.cpp @@ -11,15 +11,9 @@ namespace esphome { // === Wake-requested flag + main-loop woke flag storage === -// RP2040 is always ESPHOME_THREAD_SINGLE in real builds, but defines.h (used -// for static analysis / IDE) can define ESPHOME_THREAD_MULTI_ATOMICS alongside -// USE_RP2040, so the storage type here has to match wake.h's conditional. +// RP2040 is always ESPHOME_THREAD_SINGLE. // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) -#ifdef ESPHOME_THREAD_MULTI_ATOMICS -std::atomic g_wake_requested{0}; -#else volatile uint8_t g_wake_requested = 0; -#endif volatile bool g_main_loop_woke = false; // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)