Skip to content

fix(thread_aware): dedup factory call on first relocate when source =…#399

Draft
Vaiz wants to merge 1 commit intomainfrom
fix/thread-aware-relocate-source-equals-dest-dedup
Draft

fix(thread_aware): dedup factory call on first relocate when source =…#399
Vaiz wants to merge 1 commit intomainfrom
fix/thread-aware-relocate-source-equals-dest-dedup

Conversation

@Vaiz
Copy link
Copy Markdown
Contributor

@Vaiz Vaiz commented Apr 30, 2026

…= destination

Arc<T, S>::with_closure eagerly builds self.value for the calling thread's affinity but does not record which affinity it was. The first relocated(source, destination) call observes source from the caller — by contract the affinity of the thread that ran with_closure.

When that first relocate has source == destination, the eager self.value is already the correct per-affinity value, so reuse it instead of running the factory again.

Without this shortcut, scheduler.spawn_multiple(Instantiation::All, ...) called from a worker thread races on the storage write lock: the source==destination task can win first and factory-build (with no source-seed step, since the existing source != destination guard elides it) before any peer task populates the source slot via the end-of-function fallback. The result is one extra factory invocation non-deterministically, observable as counts > len in fetch::isolated_on_oxidizer (e.g. 9 > 8).

This complements PR #310 (which fixed storage corruption from the source == destination path) by also eliminating the extra factory call on that same path.

Replaces the previous test_relocated_source_equals_destination_does_not_corrupt_storage regression test, which was asserting the now-fixed behavior (factory re-run on first relocate(s, s)). Adds a deterministic Arc::ptr_eq test covering the new invariant.

AB#7312281

…= destination

Arc<T, S>::with_closure eagerly builds self.value for the calling
thread's affinity but does not record which affinity it was. The first
`relocated(source, destination)` call observes `source` from the
caller — by contract the affinity of the thread that ran `with_closure`.

When that first relocate has `source == destination`, the eager
`self.value` is already the correct per-affinity value, so reuse it
instead of running the factory again.

Without this shortcut, `scheduler.spawn_multiple(Instantiation::All, ...)`
called from a worker thread races on the storage write lock: the
`source==destination` task can win first and factory-build (with no
source-seed step, since the existing `source != destination` guard
elides it) before any peer task populates the source slot via the
end-of-function fallback. The result is one extra factory invocation
non-deterministically, observable as `counts > len` in
`fetch::isolated_on_oxidizer` (e.g. `9 > 8`).

This complements PR #310 (which fixed storage corruption from the
`source == destination` path) by also eliminating the extra factory
call on that same path.

Replaces the previous `test_relocated_source_equals_destination_does_not_corrupt_storage`
regression test, which was asserting the now-fixed behavior (factory
re-run on first `relocate(s, s)`). Adds a deterministic
`Arc::ptr_eq` test covering the new invariant.

AB#7312281

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.0%. Comparing base (cacf0bf) to head (fe826d1).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #399   +/-   ##
=======================================
  Coverage   100.0%   100.0%           
=======================================
  Files         225      225           
  Lines       16350    16355    +5     
=======================================
+ Hits        16350    16355    +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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