From aa683dbd764ab6d38dc840e52de98cc6dc2d07c7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 05:46:18 +0000 Subject: [PATCH] fix(library): restore the per-entry yield in the dual-core index walk dc7ab09 dropped the vTaskDelay(1) that 52b5fd6 added. The storage mutex does not hand off to a waiter, so the walk on core 0 could retake it before a Home task waiting on core 1 woke. Single-core stays yield-free. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01XgLRarbAmBVepTPKCK7mgd --- CHANGELOG.md | 1 + src/activities/library/LibraryPrewarm.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b40efe757f5..54f7d4c408c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ ### Fixed +- On the X4 Pro and Sticky, the Home screen no longer stalls waiting for the SD card while the Library indexes in the background. - Small images that are scaled up, such as a short progressive JPEG, are now cached after the first draw instead of being decoded again on every screen refresh. - The serial log no longer reports errors for normal events: a missing image, section or dictionary cache file on first open, an outdated section cache being rebuilt, and a device without a clock chip or motion sensor. Log lines that were missing a line break now end cleanly, and SD, display, TLS and frontlight messages use the standard log format. - X4 Pro light-sleep firmware shows its real version (for example `1.6.0-x4-pro`) instead of "dev" in Settings, on the boot screen, and in the web and OTA version checks. diff --git a/src/activities/library/LibraryPrewarm.cpp b/src/activities/library/LibraryPrewarm.cpp index a5dfcc1f1c8..56910bbd77d 100644 --- a/src/activities/library/LibraryPrewarm.cpp +++ b/src/activities/library/LibraryPrewarm.cpp @@ -77,6 +77,11 @@ bool serviceBuild(void*) { fullSpeed.emplace(); pausedMs += millis() - pausedAtMs; } + // Dual-core: give up the card for a tick between entries. The storage mutex + // does not hand off to a waiter, so without this the walk on core 0 can + // retake it before a Home task waiting on core 1 wakes, starving it for a + // whole directory. Single-core runs at idle priority and needs no yield. + if (portNUM_PROCESSORS > 1) vTaskDelay(1); return !cancelRequested.load(std::memory_order_acquire); }