Skip to content

tasks: the card poller and the radio were given 8 KB because nobody had measured - #119

Merged
mclueppers merged 1 commit into
mainfrom
perf/right-size-task-stacks
Sep 5, 2026
Merged

tasks: the card poller and the radio were given 8 KB because nobody had measured#119
mclueppers merged 1 commit into
mainfrom
perf/right-size-task-stacks

Conversation

@mclueppers

Copy link
Copy Markdown
Contributor

Both were the number you write when you do not know. The console now reports what each task has actually had left, so they can be sized from evidence — with the margin the consequence deserves rather than the margin the observation would allow, because a high-water mark is "worst seen" and never "worst possible".

The radio goes to 6 KB. Worth saying what does not set it: the transmit frame is a member of LoRaRadio rather than a local, so the size of a LoRa packet never lands on this stack — what does is call depth through RadioLib, the SPI transaction under it, and the receive path pushing into the ring. That is not derivable the way a buffer is, so the figure is empirical, and it is the stack that moves: it read 1.7 KB used one morning and 2.6 KB the same evening on the same firmware. 6 KB leaves more spare than the whole of what has ever been used.

The card poller goes to 6 KB and not the 4 the numbers alone would allow, because of a line sitting directly above where the task is created: at 4 KB the FAT layer tripped the canary on core 0, on mount probes and the rename that log rotation does. The probe path has been rewritten since and today's figure is 1.6 KB, but "it crashed at 4 KB once" outranks "it uses 1.6 KB this week" — one is a bound and the other is a sample. Its deepest path is a format, which runs on this task and which nothing has exercised while anybody was watching; FatFS takes that work buffer from the heap, which limits the exposure but does not remove it.

What it buys, measured on the T-Deck: 18940 bytes of free internal RAM before and 24808 after, the low-water mark from 14748 to 20400, and the largest contiguous block from 7156 to 14324. That last figure is the one that matters for the portal, and it doubled.

Which settles something that was an either/or this morning. With the speaker switched on, the portal answered in 1.6 s where the same node with the same setting used to time out entirely. Audio and the web interface fit on that board now.

Verified on both: radio online on the SX1262 and the LR1110 with packets moving, the card still polling, and neither trimmed task below 4.5 KB of headroom.

…ad measured

Both were the number you write when you do not know. The console now reports
what each task has actually had left, so they can be sized from evidence — with
the margin the consequence deserves rather than the margin the observation would
allow, because a high-water mark is "worst seen" and never "worst possible".

The radio goes to 6 KB. Worth saying what does not set it: the transmit frame is
a member of LoRaRadio rather than a local, so the size of a LoRa packet never
lands on this stack — what does is call depth through RadioLib, the SPI
transaction under it, and the receive path pushing into the ring. That is not
derivable the way a buffer is, so the figure is empirical, and it is the stack
that moves: it read 1.7 KB used one morning and 2.6 KB the same evening on the
same firmware. 6 KB leaves more spare than the whole of what has ever been used.

The card poller goes to 6 KB and not the 4 the numbers alone would allow,
because of a line sitting directly above where the task is created: at 4 KB the
FAT layer tripped the canary on core 0, on mount probes and the rename that log
rotation does. The probe path has been rewritten since and today's figure is
1.6 KB, but "it crashed at 4 KB once" outranks "it uses 1.6 KB this week" — one
is a bound and the other is a sample. Its deepest path is a format, which runs
on this task and which nothing has exercised while anybody was watching; FatFS
takes that work buffer from the heap, which limits the exposure but does not
remove it.

What it buys, measured on the T-Deck: 18940 bytes of free internal RAM before
and 24808 after, the low-water mark from 14748 to 20400, and the largest
contiguous block from 7156 to 14324. That last figure is the one that matters
for the portal, and it doubled.

Which settles something that was an either/or this morning. With the speaker
switched on, the portal answered in 1.6 s where the same node with the same
setting used to time out entirely. Audio and the web interface fit on that board
now.

Verified on both: radio online on the SX1262 and the LR1110 with packets moving,
the card still polling, and neither trimmed task below 4.5 KB of headroom.
@mclueppers
mclueppers requested a lite review from Copilot September 5, 2026 17:02
@mclueppers
mclueppers merged commit 69aaaef into main Sep 5, 2026
18 checks passed
@mclueppers
mclueppers deleted the perf/right-size-task-stacks branch September 5, 2026 17:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The stack size changes are localized, compile-time-defined, and consistently wired through Config.h without introducing API or behavioral inconsistencies beyond the intended memory reclamation.

Pull request overview

This PR reduces over-provisioned FreeRTOS task stacks for the SD card poller and LoRa radio tasks, moving the sizes into Config.h as tunable macros and documenting the empirical basis for the new values to reclaim internal RAM for other features.

Changes:

  • Replace hard-coded 8 KB task stack allocations with SD_TASK_STACK and RADIO_TASK_STACK macros.
  • Introduce documented defaults for both stacks (6 KB each) in src/Config.h, including rationale and measurement notes.
  • Update inline comments near task creation sites to point to the central sizing guidance.
File summaries
File Description
src/sys/SdCard.cpp Switch SD poller task stack from hard-coded 8192 to SD_TASK_STACK and reference the central sizing rationale.
src/main.cpp Switch radio task stack from hard-coded 8192 to RADIO_TASK_STACK.
src/Config.h Define SD_TASK_STACK / RADIO_TASK_STACK defaults (6144) and add detailed rationale for sizing and margins.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants