perf(timer): embed the waiter node in the awaitable frame#322
Conversation
Each co_await on a timer previously allocated a waiter_node from the service, amortized through a thread-local cache and a mutex-protected free list. The node now lives inside the awaitable on the suspended coroutine's frame, so a wait performs no allocation and never touches the free-list mutex. The stop token is borrowed from the awaiting chain's io_env and the stop callback is constructed in place in a raw buffer, so the node owns no destructible state. Completion paths destroy the callback and finish touching the node before posting the continuation or destroying the coroutine, whose frame is the node's storage. completion_op and canceller are defined non-inline in timer.cpp because the inline waiter_node constructor references do_complete and the vtable from translation units that reach timer.hpp through delay.hpp without including timer_service.hpp. The waiter free list, thread-local waiter cache, and per-wait create/destroy machinery are removed.
|
An automated preview of the documentation is available at https://322.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-07-17 21:57:07 UTC |
|
GCOVR code coverage report https://322.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-07-17 22:04:51 UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #322 +/- ##
===========================================
- Coverage 77.79% 77.52% -0.28%
===========================================
Files 96 96
Lines 6985 6900 -85
Branches 1682 1664 -18
===========================================
- Hits 5434 5349 -85
Misses 1055 1055
Partials 496 496
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
Each co_await on a timer previously allocated a waiter_node from the service, amortized through a thread-local cache and a mutex-protected free list. The node now lives inside the awaitable on the suspended coroutine's frame, so a wait performs no allocation and never touches the free-list mutex.
The stop token is borrowed from the awaiting chain's io_env and the stop callback is constructed in place in a raw buffer, so the node owns no destructible state. Completion paths destroy the callback and finish touching the node before posting the continuation or destroying the coroutine, whose frame is the node's storage.
completion_op and canceller are defined non-inline in timer.cpp because the inline waiter_node constructor references do_complete and the vtable from translation units that reach timer.hpp through delay.hpp without including timer_service.hpp.
The waiter free list, thread-local waiter cache, and per-wait create/destroy machinery are removed.