Skip to content

C++Now 2026 audit follow-up: cache-line fix + two spikes (Dist link blocker, static-init survey) - #764

Merged
drsnuggles8 merged 2 commits into
masterfrom
feature/cppnow26-audits
Aug 9, 2026
Merged

C++Now 2026 audit follow-up: cache-line fix + two spikes (Dist link blocker, static-init survey)#764
drsnuggles8 merged 2 commits into
masterfrom
feature/cppnow26-audits

Conversation

@drsnuggles8

@drsnuggles8 drsnuggles8 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

Four small, independent items from a C++Now 2026 conference review, deliberately not issue-sourced (filing would have cost more than doing them, or the output was unknown until measured). Full context in HANDOVER.md on this branch (gitignored, not part of this diff).

  • Item 1 — spinlock/payload cache-line audit (Pikus, Lock-Free Programming is Dead): surveyed Threading/Task/Async/Audio/Core for lock-shaped members guarding an adjacent payload on the same cache line. Fixed the one genuinely contended site that cleared the bar: Tasks::Private::FTaskBase::TSubsequents in TaskPrivate.h — its unlocked fast-path m_IsClosed read (hit on every prerequisite→subsequent edge added anywhere in the task graph) shared a line with the FMutex and TArray payload it guards. alignas(OLO_PLATFORM_CACHE_LINE_SIZE) separates them. ~2 dozen other candidates were surveyed and rejected (not contended, or the real cost was a structural single-global-lock bottleneck rather than adjacency — see the new doc). Judgement criteria + rejected candidates written up in docs/agent-rules/spinlock-payload-cache-line-separation.md, linked from CLAUDE.md.
  • Item 2 — /Gw A/B on Dist binary size (Gamberini, Leveraging the Linker): blocked before it could start. OloEngine.lib fails to link in Dist config on unmodified origin/master (LNK1248, archive >4GiB from /GL whole-program-optimization IL bloat — e.g. a single LuaScriptGlue.obj was 360MB). CI never catches it because every workflow builds Release or Debug, never Dist. Filed Dist config: OloEngine.lib exceeds the 4GiB COFF archive limit (LNK1248), CI never catches it #762 with the root-cause writeup. No /Gw change was made — there's no linkable baseline to measure against.
  • Item 3 — SPIKE: static-initializer audit via clang warnings (C++ Magic Statics Demystified): added -Wglobal-constructors/-Wexit-time-destructors to the clangcl preset only (warnings, not -Werror, never on msvc). Built OloEngine-Tests: 200 distinct sites in our own code (raw counts ~2600 but hugely inflated by inline static members warning per translation unit). Filed Static-init audit: 200 distinct -Wglobal-constructors/-Wexit-time-destructors sites in our own code (clangcl spike) #763 with the breakdown, top offenders, and representative examples (a clean string_view win in MaterialAsset.cpp vs. legitimate singleton state in NetworkManager.cpp). Flags reverted from this branch — not merged, per the spike's own decision tree.
  • Item 4 — SPIKE: mutation-test SystemScheduler (Suvorov, What is your Algorithmic Core?): hand-mutated 5 lines in SystemScheduler.cpp's Kahn-sort/tie-break logic (tie-break comparator, dropped Before() edge, off-by-one in-degree threshold, skipped cycle check, swapped Reads/Writes direction), one at a time, rebuilt, ran SystemSchedulerTest.*. All 5 caught. Good result — every mutation reverted, nothing else changed.

Net diff

Only item 1 changes shipped code — everything else is either blocked-and-documented (item 2) or a reverted spike (items 3, 4):

  • OloEngine/src/OloEngine/Task/TaskPrivate.h — the cache-line fix.
  • docs/agent-rules/spinlock-payload-cache-line-separation.md — new, the reusable lesson.
  • CLAUDE.md — one-line link to the new doc.

Follow-up issues filed

Test plan

  • OloEngine-Tests full suite (msvc Debug): 5546/5553 passed, 6 skipped (expected — GPU/app-launch tests unavailable), 1 known/tracked failure unrelated to this change (AtmosphereVisualEvidenceTest.DayNightWeatherMatrixRendersAndHoldsContracts).
  • SystemSchedulerTest.*/SystemSchedulerParallelTest.*: 26/26 passed on the final (unmutated) tree.
  • /W4 stays clean — /wd4324 is already suppressed project-wide for exactly this alignas padding pattern.
  • Item 3's flags confirmed to compile clean and warn as expected on the clangcl preset before being reverted.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Performance

    • Improved task-system concurrency by aligning related synchronization state to reduce cache-line contention during task completion and follow-up processing.
  • Documentation

    • Added guidance for identifying and addressing cache-line contention between synchronization state and protected data.
    • Documented the task-system optimization, alignment approach, and criteria for evaluating similar layouts.

…ad (C++Now 2026 audit)

FTaskBase::TSubsequents::PushIfNotClosed does an unlocked fast-path read of
m_IsClosed on every prerequisite->subsequent edge added anywhere in the task
graph, often from several worker threads racing to attach to the same shared
prerequisite. It shared a cache line with the FMutex and the TArray payload
those reads should be independent of, so Close()'s lock acquisition paid an
avoidable invalidation round-trip (Pikus, "Lock-Free Programming is Dead",
C++Now 2026). alignas() separates it, using the project's existing cache-line
constant.

Also documents the judgement criteria from the repo-wide audit that produced
this single fix (~2 dozen candidates surveyed, most rejected) in a new
docs/agent-rules note, linked from CLAUDE.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change documents cache-line separation criteria, records the audit outcome, and updates TSubsequents to store its closed flag and mutex in an aligned FCloseState structure.

Changes

Cache-Line Separation

Layer / File(s) Summary
Audit criteria and companion guidance
docs/agent-rules/spinlock-payload-cache-line-separation.md, CLAUDE.md
The documentation defines cache-line interference criteria, records rejected candidates, identifies TSubsequents as the qualifying case, and links the companion guide.
TSubsequents close-state grouping
OloEngine/src/OloEngine/Task/TaskPrivate.h
TSubsequents groups its closed flag and mutex in an aligned FCloseState. PushIfNotClosed, Close, and IsClosed use the grouped state while preserving synchronization behavior.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies the cache-line fix and the documented audit follow-ups, which are the main changes in the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@OloEngine/src/OloEngine/Task/TaskPrivate.h`:
- Around line 1091-1100: Ensure the synchronization members near m_IsClosed and
m_Mutex occupy separate cache lines by independently aligning m_Mutex or using
an appropriately sized wrapper, rather than relying on m_IsClosed alignment
alone. Update the guidance in
docs/agent-rules/spinlock-payload-cache-line-separation.md:88-89 to describe
this complete separation requirement; no other sites require changes.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 46a2cb33-cbcc-4912-be99-55d5fb2365cf

📥 Commits

Reviewing files that changed from the base of the PR and between 36541d8 and 739c38e.

📒 Files selected for processing (3)
  • CLAUDE.md
  • OloEngine/src/OloEngine/Task/TaskPrivate.h
  • docs/agent-rules/spinlock-payload-cache-line-separation.md

Comment thread OloEngine/src/OloEngine/Task/TaskPrivate.h Outdated
…s wrapper

Review feedback on #764: the previous fix relied on m_Mutex (1 byte, natural
alignment 1) landing immediately after alignas(64)'d m_IsClosed to inherit
its cache-line separation from m_Subsequents. That's correct today per C++
layout rules, but implicit — a member inserted between them, or a reorder,
would silently break it with no diagnostic. Groups both into one alignas'd
FCloseState struct instead, matching the existing FPaddedSharedTask pattern
in Task/TaskConcurrencyLimiter.h: the pairing is now structural rather than
incidental to declaration order.

Updated the accompanying docs/agent-rules note to describe the wrapper as
the actual guidance rather than "alignas the first member and trust the
rest to follow."

Validated: OloEngine-Tests full suite (5546/5553 passed, same 6 expected
skips, same 1 pre-existing/tracked failure as before this change) plus the
Task/SystemScheduler suites in isolation (73/73).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@OloEngine/src/OloEngine/Task/TaskPrivate.h`:
- Around line 1104-1109: Rename the non-static members of FCloseState from
IsClosed and Mutex to m_IsClosed and m_Mutex, then update all corresponding
accesses in the nearby close-state logic (lines 1064-1086) to use the new names.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8ae37007-8310-4330-9e21-a983ccb6a22f

📥 Commits

Reviewing files that changed from the base of the PR and between 739c38e and cf7b378.

📒 Files selected for processing (2)
  • OloEngine/src/OloEngine/Task/TaskPrivate.h
  • docs/agent-rules/spinlock-payload-cache-line-separation.md

Comment thread OloEngine/src/OloEngine/Task/TaskPrivate.h
@sonarqubecloud

sonarqubecloud Bot commented Aug 9, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
B Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@drsnuggles8
drsnuggles8 merged commit 5163a9f into master Aug 9, 2026
13 of 15 checks passed
@drsnuggles8
drsnuggles8 deleted the feature/cppnow26-audits branch August 9, 2026 08:45
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.

1 participant