You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 65106c7
Browse filesBrowse the repository at this point in the historyBrowse files
feat(io_context): decompose locking config into asio-parity tiers (#310)
Holistic follow-up to the concurrency_hint audit. Replaces the single
coarse lockless switch with a locking-tier model mirroring Boost.Asio's
SAFE / UNSAFE_IO / UNSAFE, and adds the single-run-thread optimization
asio derives from concurrency_hint == 1.
Interface:
- Add io_context_options::locking (locking_mode enum: safe / unsafe_io /
unsafe), replacing single_threaded_lockless. safe = full thread safety
(default); unsafe_io = per-descriptor I/O locks off, scheduler locks on;
unsafe = all locks off.
- concurrency_hint stays an unsigned perf knob and never changes the
safety contract; hint == 1 now engages a single-run-thread fast path
with locks still on.
Internals:
- Replace the scheduler base virtuals configure_single_threaded(bool) /
is_single_threaded() with configure_threading(threading_config) +
scheduler_locking_disabled(). threading_config carries the three
decomposed signals (scheduler_locking, reactor_io_locking, one_thread).
- reactor_scheduler: scheduler_locking gates mutex_/cond_;
reactor_io_locking gates the per-descriptor mutexes; one_thread elides
the two do_one inter-run-thread peer-wakes (unlock_and_signal_one),
keeping locks on so cross-thread post() is still woken via the foreign
post path. Private-queue routing is unchanged.
- io_uring: dispatch/cond gated by scheduler_locking, ring_mutex by
reactor_io_locking; SINGLE_ISSUER/DEFER_TASKRUN and the eventfd
interrupt elision now key on reactor-I/O locking off (single ring user,
cross-thread post forbidden) rather than the coarse flag.
- IOCP: dispatch_mutex_ gated by scheduler_locking.
- The plain io_context(unsigned) and backend-tag ctors now apply the
threading config (so hint == 1 engages one_thread on every path) via a
dedicated apply_threading_ path that deliberately leaves the reactor
budget at its defaults. They do NOT run the options ctor's multi-thread
post-everything budget heuristic — preserving the established default-
constructed behavior (routing them through the full heuristic regressed
latency-bound single-flow workloads 15-31%).
Service parity: resolver and POSIX file services now key their
operation_not_supported restriction on scheduler_locking_disabled()
(the unsafe tier only), so they remain available under unsafe_io —
matching asio, whose restriction keys on the scheduler lock.
Tests: add unsafe_io coverage (io_context runs work; resolver and file
services stay available) alongside the existing unsafe restriction tests;
keep testHintOneIsThreadSafe. Update benchmark setters to opts.locking.
Docs: rewrite the option docstring and the io-context/configuration guide
pages with the three-tier table and the corosio<->asio mapping.
Verified: 149/149 tests pass; io_context/resolver/stream_file suites
TSan-clean including the new unsafe_io tests; instrumentation confirmed
hint == 1 engages one_thread with locks on and unsafe_io yields
scheduler-locked + io-lockless. Benchmarked vs the pre-change commit
(focused categories, CCX-pinned, performance governor): safe-tier and
lockless paths performance-neutral (all diffs within noise).
0 commit comments