Commit Graph
27330 Commits
Author SHA1 Message Date
J. Nick Koston 830af94b2c Merge branch 'app-loop-optimize-speed' into integration 2026-04-12 19:57:45 -10:00
J. Nick Koston 0436e5bd86 [core] Optimize main loop with -O2
Add __attribute__((optimize("O2"))) to the main loop functions
(loop_task on ESP32, codegen loop() on other platforms) so GCC
inlines scheduler helpers and loop bookkeeping more aggressively.

Under -Os, GCC outlines small functions (Scheduler::call helpers,
millis conversions, etc.) that are called every loop iteration.
With -O2, these get inlined into the loop body, reducing call
overhead on the hottest code path in the firmware.

ESP32: loop_task grows from 303 to 416 bytes (+113 bytes).
ESP8266: no change (already fully inlined via ESPHOME_ALWAYS_INLINE).
2026-04-12 19:55:30 -10:00
J. Nick Koston d9762759c0 Merge branch 'benchmark-use-os-optimization' into proto-speed-optimized-v2 2026-04-12 19:30:45 -10:00
J. Nick Koston e1ea9cb66b Revert "Merge branch 'benchmark-crypto-o2' into integration"
This reverts commit c58447ad3a, reversing
changes made to 3b02c6d5ef.
2026-04-12 19:26:54 -10:00
J. Nick Koston d217ab3cd4 [api] Add speed_optimized proto option for hot encode paths
Add a new (speed_optimized) message option that emits
__attribute__((optimize("O2"))) on the generated encode() and
calculate_size() methods. Under -Os, GCC does not inline the small
ProtoEncode helpers (write_raw_byte, encode_varint, etc.) into the
generated methods, causing significant overhead on hot paths.

Apply to SensorStateResponse and BluetoothLERawAdvertisementsResponse
which are the highest-frequency encode paths.
2026-04-12 19:23:39 -10:00
J. Nick Koston 70dd732821 [api] Add speed_optimized proto option for hot encode paths
Add a new (speed_optimized) message option that emits
__attribute__((optimize("O2"))) on the generated encode() and
calculate_size() methods. Under -Os, GCC does not inline the small
ProtoEncode helpers (write_raw_byte, encode_varint, etc.) into the
generated methods, causing significant overhead on hot paths.

Apply to SensorStateResponse and BluetoothLERawAdvertisementsResponse
which are the highest-frequency encode paths.
2026-04-12 19:21:47 -10:00
J. Nick Koston c58447ad3a Merge branch 'benchmark-crypto-o2' into integration 2026-04-12 19:17:20 -10:00
J. Nick Koston 63184e95a2 [api] Only apply -O2 to libsodium, not noise-c
CodSpeed results show only Noise benchmarks improved with -O2 —
the speedup comes from libsodium's crypto primitives (Curve25519,
ChaCha20, Poly1305), not noise-c's protocol layer. Narrow the
optimization to libsodium only.
2026-04-12 19:15:06 -10:00
J. Nick Koston 5a250cc74f [api] Compile noise-c and libsodium with -O2 for speed
Crypto libraries are CPU-bound and benefit significantly from speed
optimization over the default -Os. Add a post: extra_script that
appends -O2 to noise-c and libsodium build flags when API noise
encryption is enabled. GCC uses the last -O flag, so this overrides
the global -Os for these libraries only.
2026-04-12 19:03:21 -10:00
J. Nick Koston 9acfeec431 Merge branch 'dev' into benchmark-use-os-optimization 2026-04-12 18:40:32 -10:00
J. Nick Koston 02f828fcbf [benchmark] Use -Os to match firmware optimization level
CodSpeed benchmarks were building with -O2, while all firmware
targets (ESP8266, ESP32, LibreTiny) use -Os. This mismatch means
the benchmarks cannot detect inlining regressions that affect real
devices — GCC under -O2 inlines functions that -Os outlines due to
its size-conscious cost model.

Switch to -Os with -ffunction-sections/-fdata-sections for proper
dead-code stripping (needed because -Os preserves references that
-O2 optimizes away at compile time).
2026-04-12 18:37:50 -10:00
J. Nick Koston ab64916c37 [benchmark] Use -Os to match firmware optimization level
CodSpeed benchmarks were building with -O2, while all firmware
targets (ESP8266, ESP32, LibreTiny) use -Os. This mismatch means
the benchmarks cannot detect inlining regressions that affect real
devices — GCC under -O2 inlines functions that -Os outlines due to
its size-conscious cost model.

Remove the -Os unflag and -O2 override so benchmarks use the
platform default -Os, matching what actually runs on devices.
2026-04-12 18:32:03 -10:00
J. Nick Koston 3b02c6d5ef Merge branch 'scheduler-inline-process-defer-queue' into integration 2026-04-12 17:51:30 -10:00
J. Nick Koston 7000b865ce [scheduler] Force-inline process_defer_queue_() fast path
process_defer_queue_() follows the same fast-path/slow-path pattern
as cleanup_() and process_to_add(): an atomic load + branch that
skips to the slow path only when work is pending. GCC currently
inlines it, but past experience shows the compiler can change its
mind when surrounding code changes. Use ESPHOME_ALWAYS_INLINE to
lock in the intended behavior.
2026-04-12 17:51:01 -10:00
J. Nick Koston 3d5a65cf0e Merge remote-tracking branch 'upstream/scheduler-inline-process-to-add' into integration 2026-04-12 17:48:14 -10:00
J. Nick Koston 939b3d383c [scheduler] Force-inline process_to_add() fast path
process_to_add() has the same pattern as cleanup_(): a one-line
inline fast path (check if to_add_ is empty) with the slow path
already out-of-line in process_to_add_slow_path_(). GCC inlines it
on ESP8266 but not on ESP32, emitting a 20-byte out-of-line body.

Use ESPHOME_ALWAYS_INLINE to guarantee inlining on all platforms.
Verified on ESP32 (xtensa-esp32):
- process_to_add() symbol eliminated from binary
- Scheduler::call() idle path: 1 out-of-line call (millis_64 only)
2026-04-12 17:47:31 -10:00
J. Nick Koston ce397799dd Merge branch 'millis64-inline-single-thread' into integration 2026-04-12 17:36:15 -10:00
J. Nick Koston 7126b01a45 Merge branch 'scheduler-inline-cleanup' into integration 2026-04-12 17:35:36 -10:00
J. Nick Koston 8fbf102ef3 [core] Inline Millis64Impl::compute() on single-threaded platforms
On ESPHOME_THREAD_SINGLE platforms (ESP8266), move the
Millis64Impl::compute() body into the header so it can be inlined at
call sites. The function is trivial: two static loads, a rollover
branch (taken every ~49.7 days), a store, and a shift+add.

The static storage (last_millis_, millis_major_) is declared as class
statics in the header and defined in time_64.cpp so all TUs share one
copy. Multi-threaded paths remain out-of-line in time_64.cpp.

Also force-inline millis_64_from_() which wraps compute() — GCC was
creating an $isra$ clone instead of inlining the wrapper.

Verified on ESP8266 (xtensa-lx106):
- Millis64Impl::compute() and millis_64_from_ symbols eliminated
- Scheduler::call() idle path: zero out-of-line calls (was 1)
- compute body inlined into 3 call sites (Scheduler::call,
  next_schedule_in, loop/millis_64)
2026-04-12 17:34:34 -10:00
J. Nick Koston 942cb0733b [scheduler] Force-inline cleanup_() fast path into Scheduler::call()
cleanup_() has a two-line fast path (check to_remove count, return
!items_.empty()) with the slow path already out-of-line in
cleanup_slow_path_(). Despite `inline` hint, GCC on Xtensa emits it
as a separate function, adding unnecessary call overhead on every
Scheduler::call() invocation even when there is nothing to clean up.

Use ESPHOME_ALWAYS_INLINE to guarantee inlining. Verified on ESP8266:
- cleanup_() symbol eliminated from binary
- Scheduler::call() grows 4 bytes (inlined fast path)
- Net savings: 23 bytes (27-byte out-of-line body removed)
- Idle loop path: 1 out-of-line call instead of 2
2026-04-12 17:26:00 -10:00
Jonathan Swoboda ac8a2467a5 [core] Fix PlatformIO progress bar rendering in subprocess mode (#15681) 2026-04-12 22:51:55 -04:00
J. Nick Koston dde66ff1e1 Merge remote-tracking branch 'upstream/dev' into integration 2026-04-12 16:39:30 -10:00
J. Nick Koston 93a5984a95 Merge branch 'ld24xx-lazy-sensor-dedup' into integration 2026-04-12 15:31:21 -10:00
J. Nick Koston 5d8dc8e62c fix missing semis 2026-04-12 15:30:30 -10:00
J. Nick Koston 099a45cf2e bot comments 2026-04-12 15:19:27 -10:00
Jesse Hills dc1dd9ebb7 Merge branch 'beta' into dev 2026-04-13 12:45:02 +12:00
Jesse Hills 0c06d78a4f Merge pull request #15675 from esphome/bump-2026.4.0b2
2026.4.0b2
2026.4.0b2
2026-04-13 12:44:27 +12:00
schrobandJ. Nick Koston 41c9ed28cd [esp32] Use static stack memory for loop task instead of heap (#15659)
Co-authored-by: J. Nick Koston <nick@koston.org>
2026-04-12 23:23:01 +00:00
J. Nick Koston 49e3bea13c Merge branch 'esp32-static-task-stack' into integration 2026-04-12 13:08:53 -10:00
J. Nick Koston 40c2ac2f8f Merge remote-tracking branch 'upstream/dev' into integration 2026-04-12 13:08:40 -10:00
J. Nick Koston 3188111da9 Merge branch 'dev' into esp32-static-task-stack 2026-04-12 12:49:36 -10:00
Jesse Hills 5608aa10a5 [CI] Don't run label workflow on closed/merged PRs (#15678) 2026-04-12 12:46:49 -10:00
J. Nick Koston dd4a367088 Merge branch 'ld24xx-lazy-sensor-dedup' into integration 2026-04-12 12:40:11 -10:00
J. Nick Koston 931ef66a2f Rename LazySensorWithDedup to SensorWithDedup
There is no lazy allocation to justify the name — it's just inline
with a null check. Drop the Lazy prefix.
2026-04-12 12:36:10 -10:00
Javier Peletier daa68a2a60 [packages] fix support packages: !include mypackages.yaml (#15677) 2026-04-13 09:48:30 +12:00
J. Nick Koston 66a3e3a705 [ld24xx] Replace heap-allocated SensorWithDedup with inline LazySensorWithDedup
Replace heap-allocated SensorWithDedup wrapper with inline
LazySensorWithDedup that stores the sensor pointer and deduplicator
directly in the component, eliminating heap allocations and reducing
RAM usage for configured sensors.
2026-04-12 11:04:17 -10:00
J. Nick Koston eb7799631d Merge remote-tracking branch 'origin/ltr390-reduce-blocking' into integration 2026-04-12 10:50:48 -10:00
Jesse Hills a408b5a4fe Bump version to 2026.4.0b2 2026-04-13 08:48:19 +12:00
Clyde StubbsandJesse Hills e264c97454 [lvgl] Fix use of rotation on host SDL (#15611)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2026-04-13 08:48:19 +12:00
J. Nick Koston 8790dec137 [packages] Fix false deprecation warning and wrong error paths in nested packages (#15605) 2026-04-13 08:48:19 +12:00
Jonathan Swoboda 6480868e6e [esp32] Bump platform to 55.03.38, Arduino to 3.3.8, ESP-IDF to 5.5.4 (#15666) 2026-04-13 08:48:19 +12:00
Jonathan Swoboda 0578e43352 [canbus] Fix canbus.send can_id compile error (#15668) 2026-04-13 08:48:19 +12:00
Jonathan Swoboda 2a89d4835f [mdns] Bump espressif/mdns to 1.11.0 (#15670) 2026-04-13 08:48:19 +12:00
dependabot[bot] 5084c61016 Bump aioesphomeapi from 44.13.2 to 44.13.3 (#15641)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 08:48:19 +12:00
dependabot[bot] b45f94d511 Bump aioesphomeapi from 44.13.1 to 44.13.2 (#15637)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 08:48:18 +12:00
J. Nick KostonandCopilot 66a4752e13 [rp2040] Fix W5500 Ethernet pbuf corruption by mirroring LWIPMutex semantics (#15624)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-13 08:48:18 +12:00
Jonathan Swoboda 4d4f78de81 [sx127x][cc1101][sx126x] Use GPIO interrupt to wake loop (#15627) 2026-04-13 08:48:18 +12:00
Kevin Ahrendt 0faa641c8a [micro_wake_word] Pin esp-nn version (#15628) 2026-04-13 08:48:18 +12:00
J. Nick Koston 0f16d27a72 [api] Add (inline_encode) proto option for sub-message inlining (#15599) 2026-04-13 08:48:18 +12:00
J. Nick Koston 835ee456a5 [mcp23016] Add interrupt pin support (#15616) 2026-04-13 08:48:18 +12:00