Skip to content

Commit 3ad0934

Browse files
committed
Add dynamic profiles dictionary
1 parent a97aa8d commit 3ad0934

7 files changed

Lines changed: 2844 additions & 664 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libdd-profiling-ffi/src/profiles/dynamic.rs

Lines changed: 120 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
use super::datatypes::{
55
ddog_prof_EncodedProfile_drop, Period, ProfileResult, SampleType, SerializeResult,
66
};
7+
use crate::arc_handle::ArcHandle;
78
use anyhow::Context;
89
use function_name::named;
910
use libdd_common_ffi::slice::{AsBytes, CharSlice, Slice};
1011
use libdd_common_ffi::{wrap_with_ffi_result, Error, Result, Timespec};
1112
use libdd_profiling::dynamic::{
12-
DynamicFunctionIndex as InnerDynamicFunctionIndex, DynamicLabel as InnerDynamicLabel,
13-
DynamicLocation as InnerDynamicLocation, DynamicProfile as InnerDynamicProfile,
13+
DynamicFunction as InnerDynamicFunction, DynamicFunctionIndex as InnerDynamicFunctionIndex,
14+
DynamicLabel as InnerDynamicLabel, DynamicLocation as InnerDynamicLocation,
15+
DynamicProfile as InnerDynamicProfile,
16+
DynamicProfilesDictionary as InnerDynamicProfilesDictionary,
1417
DynamicSample as InnerDynamicSample, DynamicStackTraceIndex as InnerDynamicStackTraceIndex,
1518
DynamicStringIndex as InnerDynamicStringIndex,
1619
};
@@ -77,6 +80,31 @@ pub struct DynamicFunctionIndex {
7780
pub value: u32,
7881
}
7982

83+
#[repr(C)]
84+
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
85+
pub struct DynamicFunction {
86+
pub name: DynamicStringIndex,
87+
pub filename: DynamicStringIndex,
88+
}
89+
90+
impl From<InnerDynamicFunction> for DynamicFunction {
91+
fn from(value: InnerDynamicFunction) -> Self {
92+
Self {
93+
name: value.name.into(),
94+
filename: value.filename.into(),
95+
}
96+
}
97+
}
98+
99+
impl From<DynamicFunction> for InnerDynamicFunction {
100+
fn from(value: DynamicFunction) -> Self {
101+
Self {
102+
name: value.name.into(),
103+
filename: value.filename.into(),
104+
}
105+
}
106+
}
107+
80108
impl From<InnerDynamicFunctionIndex> for DynamicFunctionIndex {
81109
fn from(value: InnerDynamicFunctionIndex) -> Self {
82110
Self { value: value.value }
@@ -191,18 +219,37 @@ fn ffi_sample_to_parts<'a>(
191219

192220
#[must_use]
193221
#[no_mangle]
194-
pub unsafe extern "C" fn ddog_prof_DynamicProfile_new(
222+
pub unsafe extern "C" fn ddog_prof_DynamicProfile_with_dictionary(
223+
out: *mut DynamicProfile,
224+
dict: &ArcHandle<InnerDynamicProfilesDictionary>,
225+
sample_types: Slice<SampleType>,
226+
period: Option<&Period>,
227+
start_time: Option<&Timespec>,
228+
) -> crate::profile_status::ProfileStatus {
229+
crate::ensure_non_null_out_parameter!(out);
230+
match unsafe { dynamic_profile_with_dictionary(dict, sample_types, period, start_time) } {
231+
Ok(profile) => unsafe {
232+
out.write(profile);
233+
crate::profile_status::ProfileStatus::OK
234+
},
235+
Err(err) => crate::profile_status::ProfileStatus::from(err),
236+
}
237+
}
238+
239+
unsafe fn dynamic_profile_with_dictionary(
240+
dict: &ArcHandle<InnerDynamicProfilesDictionary>,
195241
sample_types: Slice<SampleType>,
196242
period: Option<&Period>,
197243
start_time: Option<&Timespec>,
198-
) -> DynamicProfileNewResult {
199-
let sample_types = sample_types.into_slice();
244+
) -> std::result::Result<DynamicProfile, crate::ProfileError> {
245+
let sample_types = sample_types.try_as_slice()?;
200246
let period = period.copied();
201247
let start_time = start_time.map(Into::into);
202-
match InnerDynamicProfile::try_new(sample_types, period, start_time) {
203-
Ok(profile) => DynamicProfileNewResult::Ok(DynamicProfile::new(profile)),
204-
Err(err) => DynamicProfileNewResult::Err(anyhow::Error::from(err).into()),
205-
}
248+
let dict = dict.try_clone_into_arc()?;
249+
let profile =
250+
InnerDynamicProfile::try_new_with_dictionary(sample_types, period, start_time, dict)
251+
.map_err(crate::ProfileError::from_display)?;
252+
Ok(DynamicProfile::new(profile))
206253
}
207254

208255
#[no_mangle]
@@ -212,38 +259,6 @@ pub unsafe extern "C" fn ddog_prof_DynamicProfile_drop(profile: *mut DynamicProf
212259
}
213260
}
214261

215-
#[must_use]
216-
#[no_mangle]
217-
#[named]
218-
pub unsafe extern "C" fn ddog_prof_DynamicProfile_intern_string(
219-
profile: *mut DynamicProfile,
220-
s: CharSlice,
221-
) -> Result<DynamicStringIndex> {
222-
wrap_with_ffi_result!({
223-
let profile = dynamic_profile_ptr_to_inner(profile)?;
224-
let s = str::from_utf8(s.try_as_bytes()?)?;
225-
Ok::<DynamicStringIndex, anyhow::Error>(profile.intern_string(s)?.into())
226-
})
227-
}
228-
229-
#[must_use]
230-
#[no_mangle]
231-
#[named]
232-
pub unsafe extern "C" fn ddog_prof_DynamicProfile_intern_function(
233-
profile: *mut DynamicProfile,
234-
name: DynamicStringIndex,
235-
filename: DynamicStringIndex,
236-
) -> Result<DynamicFunctionIndex> {
237-
wrap_with_ffi_result!({
238-
let profile = dynamic_profile_ptr_to_inner(profile)?;
239-
Ok::<DynamicFunctionIndex, anyhow::Error>(
240-
profile
241-
.intern_function(name.into(), filename.into())?
242-
.into(),
243-
)
244-
})
245-
}
246-
247262
#[must_use]
248263
#[no_mangle]
249264
#[named]
@@ -489,24 +504,70 @@ mod tests {
489504
fn ffi_roundtrip_serializes_dynamic_profile() -> std::result::Result<(), Error> {
490505
unsafe {
491506
let sample_type = SampleType::WallTime;
492-
let mut profile = std::result::Result::from(ddog_prof_DynamicProfile_new(
507+
let mut dict = ArcHandle::<InnerDynamicProfilesDictionary>::default();
508+
std::result::Result::<(), _>::from(
509+
crate::profiles::dynamic_profiles_dictionary::ddog_prof_DynamicProfilesDictionary_new(
510+
&mut dict,
511+
),
512+
)
513+
.unwrap();
514+
let dict_ref = dict.as_inner().ok();
515+
516+
let mut function_name = DynamicStringIndex::default();
517+
std::result::Result::<(), _>::from(
518+
crate::profiles::dynamic_profiles_dictionary::ddog_prof_DynamicProfilesDictionary_insert_str(
519+
&mut function_name,
520+
dict_ref,
521+
CharSlice::from("ruby_func"),
522+
crate::profiles::utf8::Utf8Option::Validate,
523+
),
524+
)
525+
.unwrap();
526+
let mut filename = DynamicStringIndex::default();
527+
std::result::Result::<(), _>::from(
528+
crate::profiles::dynamic_profiles_dictionary::ddog_prof_DynamicProfilesDictionary_insert_str(
529+
&mut filename,
530+
dict_ref,
531+
CharSlice::from("file.rb"),
532+
crate::profiles::utf8::Utf8Option::Validate,
533+
),
534+
)
535+
.unwrap();
536+
let mut label_key = DynamicStringIndex::default();
537+
std::result::Result::<(), _>::from(
538+
crate::profiles::dynamic_profiles_dictionary::ddog_prof_DynamicProfilesDictionary_insert_str(
539+
&mut label_key,
540+
dict_ref,
541+
CharSlice::from("thread id"),
542+
crate::profiles::utf8::Utf8Option::Validate,
543+
),
544+
)
545+
.unwrap();
546+
let mut function = DynamicFunctionIndex::default();
547+
let ffi_function = DynamicFunction {
548+
name: function_name,
549+
filename,
550+
};
551+
std::result::Result::<(), _>::from(
552+
crate::profiles::dynamic_profiles_dictionary::ddog_prof_DynamicProfilesDictionary_insert_function(
553+
&mut function,
554+
dict_ref,
555+
&ffi_function,
556+
),
557+
)
558+
.unwrap();
559+
560+
let mut profile = DynamicProfile {
561+
inner: std::ptr::null_mut(),
562+
};
563+
std::result::Result::<(), _>::from(ddog_prof_DynamicProfile_with_dictionary(
564+
&mut profile,
565+
&dict,
493566
Slice::from_raw_parts(&sample_type, 1),
494567
None,
495568
None,
496-
))?;
497-
498-
let function_name =
499-
ddog_prof_DynamicProfile_intern_string(&mut profile, CharSlice::from("ruby_func"))
500-
.unwrap();
501-
let filename =
502-
ddog_prof_DynamicProfile_intern_string(&mut profile, CharSlice::from("file.rb"))
503-
.unwrap();
504-
let function =
505-
ddog_prof_DynamicProfile_intern_function(&mut profile, function_name, filename)
506-
.unwrap();
507-
let label_key =
508-
ddog_prof_DynamicProfile_intern_string(&mut profile, CharSlice::from("thread id"))
509-
.unwrap();
569+
))
570+
.unwrap();
510571

511572
let locations = [DynamicLocation { function, line: 27 }];
512573
let labels = [DynamicLabel {
@@ -551,6 +612,9 @@ mod tests {
551612

552613
ddog_prof_EncodedProfile_drop(&mut encoded);
553614
ddog_prof_DynamicProfile_drop(&mut profile);
615+
crate::profiles::dynamic_profiles_dictionary::ddog_prof_DynamicProfilesDictionary_drop(
616+
&mut dict,
617+
);
554618
Ok(())
555619
}
556620
}

0 commit comments

Comments
 (0)