Skip to content
Merged
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
2 changes: 1 addition & 1 deletion libdd-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const_format = "0.2.34"
nix = { version = "0.29", features = ["process"] }
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.52"
features = ["Win32_Foundation", "Win32_System_Performance"]
features = ["Win32_Foundation", "Win32_System_Performance", "Win32_System_Threading"]

[target.'cfg(unix)'.dependencies]
rustls = { version = "0.23", default-features = false, optional = true, features = ["aws-lc-rs"] }
Expand Down
1 change: 1 addition & 0 deletions libdd-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub mod rate_limiter;
pub mod tag;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;
pub mod threading;
pub mod timeout;
pub mod unix_utils;
pub mod worker;
Expand Down
36 changes: 36 additions & 0 deletions libdd-common/src/threading.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

/// Returns a numeric identifier for the current OS thread.
#[cfg(target_os = "linux")]
pub fn get_current_thread_id() -> i64 {
// SAFETY: syscall(SYS_gettid) has no preconditions for current thread.
unsafe { libc::syscall(libc::SYS_gettid) as i64 }
}

/// Returns a numeric identifier for the current OS thread.
#[cfg(target_os = "macos")]
pub fn get_current_thread_id() -> i64 {
let mut tid: u64 = 0;
// SAFETY: `pthread_threadid_np` has no preconditions for current thread
// when pthread_t is 0 and output pointer is valid.
let rc = unsafe { libc::pthread_threadid_np(0, &mut tid) };
debug_assert_eq!(
rc,
0,
"pthread_threadid_np failed: {rc} ({})",
std::io::Error::from_raw_os_error(rc)
);
tid as i64
}

/// Returns a numeric identifier for the current OS thread.
#[cfg(target_os = "windows")]
pub fn get_current_thread_id() -> i64 {
// SAFETY: GetCurrentThreadId has no preconditions.
unsafe { windows_sys::Win32::System::Threading::GetCurrentThreadId() as i64 }
}

/// Returns a numeric identifier for the current OS thread.
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
compile_error!("libdd_common::threading::get_current_thread_id is unsupported on this platform");
16 changes: 12 additions & 4 deletions libdd-profiling/benches/add_samples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// SPDX-License-Identifier: Apache-2.0

use criterion::*;
use libdd_common::threading::get_current_thread_id;
use libdd_profiling::api2::Location2;
use libdd_profiling::profiles::datatypes::{Function, FunctionId2, MappingId2};
use libdd_profiling::profiles::datatypes::{Function, FunctionId2, MappingId2, StringId2};
use libdd_profiling::{self as profiling, api, api2};

fn make_sample_types() -> Vec<api::SampleType> {
Expand Down Expand Up @@ -103,6 +104,14 @@ pub fn bench_add_sample_vs_add2(c: &mut Criterion) {

let strings = dict.strings();
let functions = dict.functions();
let thread_id = get_current_thread_id();
let thread_id_key: StringId2 = strings.try_insert("thread id").unwrap().into();
let labels_api = vec![api::Label {
key: "thread id",
str: "",
num: thread_id,
num_unit: "",
}];

let frames2 = frames.map(|f| {
let set_id = functions
Expand All @@ -127,7 +136,7 @@ pub fn bench_add_sample_vs_add2(c: &mut Criterion) {
let sample = api::Sample {
locations: locations.clone(),
values: &values,
labels: vec![],
labels: labels_api.clone(),
};
black_box(profile.try_add_sample(sample, None)).unwrap();
}
Expand All @@ -145,8 +154,7 @@ pub fn bench_add_sample_vs_add2(c: &mut Criterion) {
.unwrap();
let (locations, values) = make_stack_api2(frames2.as_slice());
for _ in 0..1000 {
// Provide an empty iterator for labels conversion path
let labels_iter = std::iter::empty::<anyhow::Result<api2::Label>>();
let labels_iter = [Ok(api2::Label::num(thread_id_key, thread_id, ""))].into_iter();
// SAFETY: all ids come from the profile's dictionary.
black_box(unsafe {
profile.try_add_sample2(&locations, &values, labels_iter, None)
Expand Down
Loading