2121#include < atomic>
2222#include < cassert>
2323#include < cstdlib>
24+ #include < sys/sdt.h>
2425#include < unistd.h>
2526
2627namespace ddprof {
@@ -100,45 +101,49 @@ DDRes AllocationTracker::allocation_tracking_init(
100101 DDRES_RETURN_ERROR_LOG (DD_WHAT_UKNW, " Allocation profiler already started" );
101102 }
102103
103- DDRES_CHECK_FWD (instance->init (allocation_profiling_rate,
104- flags & kDeterministicSampling ,
105- flags & kTrackDeallocations , stack_sample_size,
106- ring_buffer, timer_check));
104+ DDRES_CHECK_FWD (instance->init (allocation_profiling_rate, flags,
105+ stack_sample_size, ring_buffer, timer_check));
107106 _instance = instance;
108107
109108 state.init (true , flags & kTrackDeallocations );
110109
111110 return {};
112111}
113112
114- DDRes AllocationTracker::init (uint64_t mem_profile_interval,
115- bool deterministic_sampling,
116- bool track_deallocations,
113+ DDRes AllocationTracker::init (uint64_t mem_profile_interval, uint32_t flags,
117114 uint32_t stack_sample_size,
118115 const RingBufferInfo &ring_buffer,
119116 const IntervalTimerCheck &timer_check) {
120117 _sampling_interval = mem_profile_interval;
121- _deterministic_sampling = deterministic_sampling ;
118+ _deterministic_sampling = flags & kDeterministicSampling ;
122119 _stack_sample_size = stack_sample_size;
123- if (ring_buffer.ring_buffer_type !=
124- static_cast <int >(RingBufferType::kMPSCRingBuffer )) {
125- return ddres_error (DD_WHAT_PERFRB);
120+ _otel_profiler_mode = flags & kOtelProfilerMode ;
121+
122+ if (!_otel_profiler_mode) {
123+ if (ring_buffer.ring_buffer_type !=
124+ static_cast <int >(RingBufferType::kMPSCRingBuffer )) {
125+ return ddres_error (DD_WHAT_PERFRB);
126+ }
127+
128+ DDRES_CHECK_FWD (ddprof::ring_buffer_attach (ring_buffer, &_pevent));
129+
130+ const auto &rb = _pevent.rb ;
131+ if (rb.tsc_available ) {
132+ TscClock::init (TscClock::CalibrationParams{
133+ .offset = TscClock::time_point{TscClock::duration{rb.time_zero }},
134+ .mult = rb.time_mult ,
135+ .shift = rb.time_shift });
136+ }
137+ PerfClock::init (static_cast <PerfClockSource>(rb.perf_clock_source ));
138+ } else {
139+ PerfClock::init (PerfClockSource::kClockMonotonic );
126140 }
127- if (track_deallocations) {
141+
142+ if (flags & kTrackDeallocations ) {
128143 // 16 times as we want to probability of collision to be low enough
129144 _allocated_address_set = AddressBitset (liveallocation::kMaxTracked *
130145 k_ratio_max_elt_to_bitset_size);
131146 }
132- DDRES_CHECK_FWD (ddprof::ring_buffer_attach (ring_buffer, &_pevent));
133-
134- const auto &rb = _pevent.rb ;
135- if (rb.tsc_available ) {
136- TscClock::init (TscClock::CalibrationParams{
137- .offset = TscClock::time_point{TscClock::duration{rb.time_zero }},
138- .mult = rb.time_mult ,
139- .shift = rb.time_shift });
140- }
141- PerfClock::init (static_cast <PerfClockSource>(rb.perf_clock_source ));
142147
143148 _interval_timer_check = timer_check;
144149 if (_interval_timer_check.is_set ()) {
@@ -282,6 +287,7 @@ void AllocationTracker::track_deallocation(uintptr_t addr,
282287DDRes AllocationTracker::push_lost_sample (MPSCRingBufferWriter &writer,
283288 TrackerThreadLocalState &tl_state,
284289 bool ¬ify_needed) {
290+ DDPROF_DCHECK_FATAL (!_otel_profiler_mode);
285291 auto lost_count = _state.lost_count .exchange (0 , std::memory_order_acq_rel);
286292 if (lost_count == 0 ) {
287293 return {};
@@ -322,6 +328,12 @@ DDRes AllocationTracker::push_lost_sample(MPSCRingBufferWriter &writer,
322328// Return true if consumer should be notified
323329DDRes AllocationTracker::push_clear_live_allocation (
324330 TrackerThreadLocalState &tl_state) {
331+ if (_otel_profiler_mode) {
332+ // NOLINTNEXTLINE
333+ DTRACE_PROBE (ddprof, clear_live_allocations);
334+ check_timer (PerfClock::now (), tl_state);
335+ return {};
336+ }
325337 MPSCRingBufferWriter writer{&_pevent.rb };
326338 bool timeout = false ;
327339
@@ -361,6 +373,13 @@ DDRes AllocationTracker::push_clear_live_allocation(
361373
362374DDRes AllocationTracker::push_dealloc_sample (
363375 uintptr_t addr, TrackerThreadLocalState &tl_state) {
376+ if (_otel_profiler_mode) {
377+ // NOLINTNEXTLINE
378+ DTRACE_PROBE1 (ddprof, deallocation, addr);
379+ check_timer (PerfClock::now (), tl_state);
380+ return {};
381+ }
382+
364383 MPSCRingBufferWriter writer{&_pevent.rb };
365384 bool notify_consumer{false };
366385
@@ -414,6 +433,13 @@ DDRes AllocationTracker::push_dealloc_sample(
414433DDRes AllocationTracker::push_alloc_sample (uintptr_t addr,
415434 uint64_t allocated_size,
416435 TrackerThreadLocalState &tl_state) {
436+ if (_otel_profiler_mode) {
437+ // NOLINTNEXTLINE
438+ DTRACE_PROBE2 (ddprof, allocation, addr, allocated_size);
439+ check_timer (PerfClock::now (), tl_state);
440+ return {};
441+ }
442+
417443 MPSCRingBufferWriter writer{&_pevent.rb };
418444 bool notify_consumer{false };
419445
@@ -427,12 +453,12 @@ DDRes AllocationTracker::push_alloc_sample(uintptr_t addr,
427453 const auto *stack_base_ptr = reinterpret_cast <const std::byte *>(&p);
428454 auto stack_size = to_address (tl_state.stack_bounds .end ()) - stack_base_ptr;
429455
430- // stack will be saved in save_context, add some margin to account for call
456+ // stack will be saved in save_context, add some ` to account for call
431457 // frames
432458#ifdef NDEBUG
433459 constexpr int64_t kStackMargin = 192 ;
434460#else
435- constexpr int64_t kStackMargin = 720 ;
461+ constexpr int64_t kStackMargin = 4000 ;
436462#endif
437463 uint32_t const sample_stack_size =
438464 align_up (std::min (std::max (stack_size + kStackMargin , 0L ),
0 commit comments