Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tracing-subscriber/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ env-filter = ["matchers", "regex", "once_cell", "tracing", "std", "thread_local"
fmt = ["registry", "std"]
ansi = ["fmt", "nu-ansi-term"]
registry = ["sharded-slab", "thread_local", "std"]
# Raises the sharded-slab MAX_THREADS limit from 4 096 to 131 072.
# Enable on high-core nodes where many native threads are spawned.
large-thread-count = []
json = ["tracing-serde", "serde", "serde_json"]
valuable = ["tracing-core/valuable", "valuable_crate", "valuable-serde", "tracing-serde/valuable"]
# Enables support for local time when using the `time` crate timestamp
Expand Down
35 changes: 30 additions & 5 deletions tracing-subscriber/src/registry/sharded.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
use sharded_slab::{pool::Ref, Clear, Pool};
use sharded_slab::{pool::Ref, Clear, Config, Pool};

/// Custom [`sharded_slab::Config`] for the span registry pool.
///
/// When the `large-thread-count` feature is enabled, `MAX_THREADS` is raised
/// from the upstream default of 4 096 to 131 072, preventing panics on
/// high-core machines where large numbers of native threads are spawned.
/// When the feature is disabled the trait default (4 096) is used unchanged.
#[derive(Debug)]
struct SlabConfig;

impl Config for SlabConfig {
/// 131 072 threads = 2^17. Only active with the `large-thread-count`
/// feature; otherwise falls back to the trait default of 4 096.
#[cfg(feature = "large-thread-count")]
const MAX_THREADS: usize = 131_072;
}
use thread_local::ThreadLocal;

use super::stack::SpanStack;
Expand Down Expand Up @@ -90,7 +106,7 @@ use tracing_core::{
#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))]
#[derive(Debug)]
pub struct Registry {
spans: Pool<DataInner>,
spans: Pool<DataInner, SlabConfig>,
current_spans: ThreadLocal<RefCell<SpanStack>>,
next_filter_id: u8,
}
Expand All @@ -109,7 +125,7 @@ pub struct Registry {
#[derive(Debug)]
pub struct Data<'a> {
/// Immutable reference to the pooled `DataInner` entry.
inner: Ref<'a, DataInner>,
inner: Ref<'a, DataInner, SlabConfig>,
}

/// Stored data associated with a span.
Expand All @@ -135,7 +151,7 @@ struct DataInner {
impl Default for Registry {
fn default() -> Self {
Self {
spans: Pool::new(),
spans: Pool::new_with_config::<SlabConfig>(),
current_spans: ThreadLocal::new(),
next_filter_id: 0,
}
Expand Down Expand Up @@ -180,7 +196,7 @@ pub(crate) struct CloseGuard<'a> {
}

impl Registry {
fn get(&self, id: &Id) -> Option<Ref<'_, DataInner>> {
fn get(&self, id: &Id) -> Option<Ref<'_, DataInner, SlabConfig>> {
self.spans.get(id_to_idx(id))
}

Expand Down Expand Up @@ -905,4 +921,13 @@ mod tests {
state.assert_closed_in_order(["child", "parent", "grandparent"]);
});
}

#[cfg(feature = "large-thread-count")]
#[test]
fn large_thread_count_raises_max_threads() {
assert_eq!(SlabConfig::MAX_THREADS, 131_072);
// Confirm the registry pool is parameterised on SlabConfig at the type
// level — this is a compile-time check dressed as a runtime test.
let _: &Pool<DataInner, SlabConfig> = &Pool::new_with_config::<SlabConfig>();
}
}
Loading