datadog 2.44.0 → 2.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +114 -141
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -5
- data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +0 -2
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +13 -13
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.h +5 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +1 -0
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +106 -103
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +3 -3
- data/ext/datadog_profiling_native_extension/extconf.rb +2 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +2 -2
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +98 -54
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +5 -2
- data/ext/datadog_profiling_native_extension/profiling.c +21 -23
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +3 -1
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +4 -0
- data/ext/datadog_profiling_native_extension/setup_signal_handler.c +0 -2
- data/ext/datadog_profiling_native_extension/stack_recorder.c +6 -24
- data/ext/datadog_profiling_native_extension/stack_recorder.h +0 -1
- data/ext/datadog_profiling_native_extension/time_helpers.c +2 -4
- data/ext/datadog_profiling_native_extension/time_helpers.h +10 -11
- data/ext/libdatadog_api/trace_exporter.c +77 -11
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -0
- data/lib/datadog/profiling/component.rb +2 -3
- data/lib/datadog/profiling/exporter.rb +7 -5
- data/lib/datadog/tracing/component.rb +1 -1
- data/lib/datadog/tracing/configuration/settings.rb +3 -2
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +6 -3
- data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -0
- data/lib/datadog/tracing/transport/native.rb +22 -21
- data/lib/datadog/version.rb +1 -1
- metadata +5 -5
|
@@ -53,8 +53,6 @@ void gc_profiling_init(void) {
|
|
|
53
53
|
shady_sym = ID2SYM(rb_intern_const("shady"));
|
|
54
54
|
force_sym = ID2SYM(rb_intern_const("force"));
|
|
55
55
|
oldmalloc_sym = ID2SYM(rb_intern_const("oldmalloc"));
|
|
56
|
-
state_sym = ID2SYM(rb_intern_const("state"));
|
|
57
|
-
none_sym = ID2SYM(rb_intern_const("none"));
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
bool gc_profiling_has_major_gc_finished(void) {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
typedef enum { ACTION_WAIT, ACTION_RUN, ACTION_STOP } action;
|
|
23
23
|
|
|
24
24
|
// Contains state for a single CpuAndWallTimeWorker instance
|
|
25
|
-
|
|
25
|
+
struct idle_sampling_loop_state {
|
|
26
26
|
pthread_mutex_t wakeup_mutex;
|
|
27
27
|
pthread_cond_t wakeup;
|
|
28
28
|
action requested_action;
|
|
29
29
|
void (*run_action_function)(void);
|
|
30
|
-
}
|
|
30
|
+
};
|
|
31
31
|
|
|
32
32
|
static VALUE _native_new(VALUE klass);
|
|
33
33
|
static void reset_state(idle_sampling_loop_state *state);
|
|
@@ -39,7 +39,7 @@ static void *run_idle_sampling_loop(void *state_ptr);
|
|
|
39
39
|
static void interrupt_idle_sampling_loop(void *state_ptr);
|
|
40
40
|
static VALUE _native_reset(DDTRACE_UNUSED VALUE self, VALUE self_instance);
|
|
41
41
|
static VALUE _native_idle_sampling_helper_request_action(DDTRACE_UNUSED VALUE self, VALUE self_instance);
|
|
42
|
-
static void *request_testing_action(void *
|
|
42
|
+
static void *request_testing_action(void *state_ptr);
|
|
43
43
|
static void grab_gvl_and_run_testing_action(void);
|
|
44
44
|
static void *run_testing_action(DDTRACE_UNUSED void *unused);
|
|
45
45
|
|
|
@@ -215,15 +215,14 @@ static VALUE _native_stop(DDTRACE_UNUSED VALUE self, VALUE self_instance) {
|
|
|
215
215
|
return Qtrue;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
void idle_sampling_helper_request_action(VALUE self_instance, void (*run_action_function)(void)) {
|
|
218
|
+
idle_sampling_loop_state *idle_sampling_helper_get_state(VALUE self_instance) {
|
|
220
219
|
idle_sampling_loop_state *state;
|
|
221
|
-
if (!rb_typeddata_is_kind_of(self_instance, &idle_sampling_helper_typed_data)) {
|
|
222
|
-
grab_gvl_and_raise(rb_eTypeError, "Wrong argument for idle_sampling_helper_request_action");
|
|
223
|
-
}
|
|
224
|
-
// This should never fail when the above check passes
|
|
225
220
|
TypedData_Get_Struct(self_instance, idle_sampling_loop_state, &idle_sampling_helper_typed_data, state);
|
|
221
|
+
return state;
|
|
222
|
+
}
|
|
226
223
|
|
|
224
|
+
// Called without the GVL, so we access native state directly: touching the Ruby self_instance is unsafe during GC compaction.
|
|
225
|
+
void idle_sampling_helper_request_action(idle_sampling_loop_state *state, void (*run_action_function)(void)) {
|
|
227
226
|
ENFORCE_SUCCESS_NO_GVL(pthread_mutex_lock(&state->wakeup_mutex));
|
|
228
227
|
if (state->requested_action == ACTION_WAIT) {
|
|
229
228
|
state->requested_action = ACTION_RUN;
|
|
@@ -238,13 +237,14 @@ void idle_sampling_helper_request_action(VALUE self_instance, void (*run_action_
|
|
|
238
237
|
// Because the idle_sampling_helper_request_action is built to be called without the global VM lock, here we release it
|
|
239
238
|
// to be able to call that API.
|
|
240
239
|
static VALUE _native_idle_sampling_helper_request_action(DDTRACE_UNUSED VALUE self, VALUE self_instance) {
|
|
241
|
-
|
|
240
|
+
idle_sampling_loop_state *state = idle_sampling_helper_get_state(self_instance);
|
|
241
|
+
rb_thread_call_without_gvl(request_testing_action, state, NULL, NULL);
|
|
242
|
+
RB_GC_GUARD(self_instance);
|
|
242
243
|
return Qtrue;
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
static void *request_testing_action(void *
|
|
246
|
-
|
|
247
|
-
idle_sampling_helper_request_action(self_instance, grab_gvl_and_run_testing_action);
|
|
246
|
+
static void *request_testing_action(void *state_ptr) {
|
|
247
|
+
idle_sampling_helper_request_action(state_ptr, grab_gvl_and_run_testing_action);
|
|
248
248
|
return NULL;
|
|
249
249
|
}
|
|
250
250
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
typedef struct idle_sampling_loop_state idle_sampling_loop_state;
|
|
4
|
+
|
|
5
|
+
// Must be called with the GVL held; keep self_instance alive while using the returned pointer.
|
|
6
|
+
idle_sampling_loop_state *idle_sampling_helper_get_state(VALUE self_instance);
|
|
7
|
+
void idle_sampling_helper_request_action(idle_sampling_loop_state *state, void (*run_action_function)(void));
|
|
@@ -641,6 +641,7 @@ void record_placeholder_stack(
|
|
|
641
641
|
);
|
|
642
642
|
}
|
|
643
643
|
|
|
644
|
+
// Also called from a signal handler or during GC; check callers' safety requirements before changing this function.
|
|
644
645
|
bool prepare_sample_thread(VALUE thread, sampling_buffer *buffer) {
|
|
645
646
|
// While the signal handler checks if there's GC going on, it's actually possible for `sampling_buffer_mark` to
|
|
646
647
|
// still run outside of GC (see comments on that function) and thus we guard for it here.
|