perf(sync)!: defer shared writer wake allocation - #1068
Conversation
There was a problem hiding this comment.
Pull request overview
Defers wake-state allocation for ready no-token shared-mutex writers while preserving writer admission and cancellation behavior.
Changes:
- Lazily allocates writer wake state on suspension.
- Adds allocation, failure, race, and token-path tests.
- Extends benchmarks and documentation for writer performance.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
include/elio/sync/shared_mutex.hpp |
Implements deferred writer allocation. |
tests/unit/test_sync_cancellation.cpp |
Adds writer allocation regressions. |
examples/shared_mutex_reader_benchmark.cpp |
Adds writer benchmark workloads. |
examples/CMakeLists.txt |
Enables benchmark test hooks. |
wiki/Performance-Tuning.md |
Documents measurement policy. |
wiki/API-Reference.md |
Documents allocation and exception behavior. |
wiki/API-Contracts.md |
Updates shared-mutex contract. |
CHANGELOG.md |
Records the breaking performance change. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
f272093 to
5664738
Compare
|
@copilot please re-review only; do not make direct code modifications. |
Re-reviewed the current head. All three questions from the PR are answered cleanly: 1. No no-token path dereferences an empty Every 2. The
3. The timing/probe target separation is sufficient.
|
Description
Make ready no-token
shared_mutex::lock()acquisitions allocation-free while preserving the existing writer-admission and preference state machine.The writer waiter now creates independently owned wake state only when suspension entry is reached. Allocation happens before the queue mutex,
WRITER_WAITING, pending-writer accounting, or queue publication, sostd::bad_allochas the strong guarantee that no writer state changed. Token-aware writers remain eager.This intentionally removes
noexceptfrom the no-token writer awaiter's low-levelawait_suspend()member. The ownership result and high-levelco_await mutex.lock()usage are unchanged, but code that explicitly depends on that exception specification must allowstd::bad_allocon the contended path.Type of Change
Related Issues
Closes #1041
Related to #1040
Changes Made
Core Changes
API Changes
Before:
After:
Migration Guide
Ordinary
co_await mutex.lock()call sites need no source change. Low-level code that explicitly requires the no-token writer awaiter'sawait_suspend()to benoexceptmust remove that assumption and may handlestd::bad_allocfrom a contended acquisition. Allocation failure occurs before writer preference, pending-writer accounting, or queue state is changed.Testing
Unit Tests
Integration Tests
Sanitizer Testing
Test Results
Controlled local Release measurements used identical final uninstrumented source and flags, fixed distinct physical CPU sets, 30 balanced interleaved process pairs per workload, strict accounting/timeouts, and 200,000 order-stratified bootstrap resamples. Only the Elio include root differed. A separately instrumented build proved the exact allocation delta; its timing was discarded.
Checklist
Code Quality
Documentation
Testing
Compatibility
Performance
Screenshots / Diagrams
Not applicable.
Additional Notes
The original W0 experiment and the first current-main timing generation remain visible in #1041. The original raw-maximum gate was prospectively superseded, while the first current-main timing was invalidated when review found that test-only allocation instrumentation biased the baseline. The final table above comes from a fresh uninstrumented generation; no earlier samples were pooled or reused.
GitHub-hosted CI is used only for correctness, compatibility, sanitizers, and timeout-bounded smoke. It has no timing threshold. In controlled local evidence, sub-3% differences are treated as approximately neutral unless exact mechanism evidence exists. Acceptance here rests on the exact 1-to-0 ready allocation change, the simpler reader/writer-symmetric contract already established by #1040, unchanged writer preference/progress, strong allocation-failure safety, and the absence of a material controlled regression.
Reviewer Guidance
Areas requiring special attention:
WRITER_WAITING, pending-writer accounting, or waiter publication.ELIO_RUNTIME_TEST_HOOKS; only the separate allocation probe may enable them.Questions for reviewers:
await_suspend()exception-specification change complete and accurate?