Skip to content

Conversation

@TheJokr
Copy link
Collaborator

@TheJokr TheJokr commented Nov 27, 2025

Improve performance of log/tracing harness access

  • Switch to std::sync::{OnceLock, LazyLock} for better storage
    efficiency and std's futex-based backend. These are available since
    Rust 1.80.
  • Avoid unnecessary LazyLock initialization of NOOP_HARNESS if a
    proper harness is configured. Previously, .unwrap_or(&NOOP_HARNESS)
    would cause the Deref impl to be called even if the reference was
    never used. (Due to Deref's side effects.)
  • Wrap harnesses in crossbeam's CachePadded to avoid false sharing
    with other global variables. This is important to ensure OnceLock's
    initialization check is not slowed down by dirty cache lines.

Remove globally-shared INACTIVE_SPAN RwLock

This RwLock was a heavy contention point in applications that generate a
lot of spans, as every span operation must lock and unlock the RwLock.
Each lock/unlock is an atomic RMW and thus dirties the cache line for
all other cores.

We can avoid the global singleton INACTIVE_SPAN entirely with some
changes to our internal SharedSpanHandle API.

Remove internal once_cell usages

There are two spots left where we can't remove once-cell yet:

  • In memory_profiler.rs, we use OnceCell::get_or_try_init. This
    function is not stabilized in std yet.
  • The foundations::security::allow_list macro generates OnceCell
    instances in user code. Changing this requires a major bump.

- Switch to `std::sync::{OnceLock, LazyLock}` for better storage
  efficiency and std's futex-based backend. These are available since
  Rust 1.80.
- Avoid unnecessary LazyLock initialization of `NOOP_HARNESS` if a
  proper harness is configured. Previously, `.unwrap_or(&NOOP_HARNESS)`
  would cause the Deref impl to be called even if the reference was
  never used.
- Wrap harnesses in crossbeam's `CachePadded` to avoid false sharing
  with other global variables. This is important to ensure OnceLock's
  initialization check is not slowed down by dirty cache lines.
There are two spots left where we can't remove once-cell yet:
- In `memory_profiler.rs`, we use `OnceCell::get_or_try_init`. This
  function is not stabilized in std yet.
- The `foundations::security::allow_list` macro generates OnceCell
  instances in user code. Changing this requires a major bump.
@TheJokr TheJokr force-pushed the lblocher/harness-get branch from 8afb2a4 to 85d867a Compare November 27, 2025 09:54
This RwLock was a heavy contention point in applications that generate a
lot of spans, as every span operation must lock and unlock the RwLock.
Each lock/unlock is an atomic RMW and thus dirties the cache line for
all other cores.

We can avoid the global singleton `INACTIVE_SPAN` entirely with some
changes to our internal `SharedSpanHandle` API.
@TheJokr TheJokr force-pushed the lblocher/harness-get branch from 85d867a to 3a028ea Compare November 27, 2025 10:51
@TheJokr TheJokr merged commit df49480 into main Nov 27, 2025
20 checks passed
@TheJokr TheJokr deleted the lblocher/harness-get branch November 27, 2025 16:36
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.

2 participants