Skip to content

Respect max_align_t (IDFGH-17761)#18686

Open
ltowarek wants to merge 1 commit into
espressif:masterfrom
ltowarek:fix_alignment
Open

Respect max_align_t (IDFGH-17761)#18686
ltowarek wants to merge 1 commit into
espressif:masterfrom
ltowarek:fix_alignment

Conversation

@ltowarek
Copy link
Copy Markdown

@ltowarek ltowarek commented Jun 3, 2026

Description

Align all pointers with max_align_t to match C/C++ specification.

Related

Fixes #18685

Testing


Checklist

Before submitting a Pull Request, please ensure the following:

  • 🚨 This PR does not introduce breaking changes.
  • All CI checks (GH Actions) pass.
  • Documentation is updated as needed.
  • Tests are updated or added as necessary.
  • Code is well-commented, especially in complex areas.
  • Git history is clean — commits are squashed to the minimum necessary.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 3, 2026

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot changed the title Respect max_align_t Respect max_align_t (IDFGH-17761) Jun 3, 2026
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jun 3, 2026
@SoucheSouche
Copy link
Copy Markdown
Collaborator

@ltowarek thanks for reporting the issue. I have reviewed the proposed changes and while it is true that the C/C++ standard deviation exists, I don't think this change is the right trade-off for ESP-IDF.

TLSF's natural alignment granularity (ALIGN_SIZE) is hardcoded to 4 bytes (ALIGN_SIZE_LOG2 = 2 in tlsf_control_functions.h). This has been the case since the TLSF was introduced as the heap allocator in the heap component about 5 years ago and heap_caps_malloc_base() was explicitly written to pass UNALIGNED_MEM_ALIGNMENT_BYTES = 4 to keep allocations on the fast multi_heap_malloc() path. This was not an oversight — it was a deliberate decision to minimize per-allocation overhead on memory-constrained MCUs.

Several targets have TLSF baked into ROM and the ROM implementation has ALIGN_SIZE = 4 and cannot be patched. The only way to get stricter alignment is to route every malloc() through tlsf_memalign_offs(), which is what this PR does — but that has significant consequences.

Routing every allocation through the memalign path imposes overhead on every user, not just those who need it:

  • Memory overhead: up to alignment + block_header extra bytes per allocation. On Xtensa targets where alignof(max_align_t) = 8, that's up to ~20 bytes per allocation. On RISC-V targets where alignof(max_align_t) = 16, it's up to ~28 bytes. On devices with 320–400 KB of RAM, this adds up quickly across hundreds or thousands of allocations.
  • Performance: tlsf_memalign_offs() must search for an inflated block size and potentially front-split, which is slower than the direct multi_heap_malloc() path.
  • Fragmentation: the memalign path creates more block splits, increasing heap fragmentation over time.
  • Complexity in realloc: the new is_shrink optimization relies on undocumented TLSF internal invariants (shrink always returns the same pointer), with special-casing for CONFIG_HEAP_POISONING_COMPREHENSIVE and ptr_in_diram_case. This makes the code harder to maintain and fragile if TLSF behavior ever changes.

This deviation has existed for years and this is the first report. The libraries affected — protobuf, abseil, OpenTelemetry — are heavyweight C++ frameworks that perform arena allocation with alignof(max_align_t)-based pointer arithmetic. The vast majority of ESP-IDF users writing C code or using lightweight C++ are unaffected. Other embedded allocators (FreeRTOS, Zephyr) have similar deviations without treating them as critical.

@SoucheSouche
Copy link
Copy Markdown
Collaborator

As a workaround, you can opt in to max_align_t alignment at the application level by overriding malloc/calloc/realloc in your project.

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

Labels

Status: Opened Issue is new

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pointers are not aligned to max_align_t (IDFGH-17760)

4 participants