Skip to content

Commit b8e2da8

Browse files
parttimenerdjbachorik
authored andcommitted
Compute actual sampling period via si_overrun
1 parent 3fb8966 commit b8e2da8

File tree

2 files changed

+11
-68
lines changed

2 files changed

+11
-68
lines changed

src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp

Lines changed: 10 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
#include "runtime/vmThread.hpp"
4646

4747
#include "signals_posix.hpp"
48-
#include <sys/utsname.h>
4948

5049
static const int64_t AUTOADAPT_INTERVAL_MS = 100;
5150

@@ -367,12 +366,6 @@ class JfrTraceQueues {
367366
}
368367
};
369368

370-
static const int64_t MINIMAL_PERIOD_NOT_FOUND = -1;
371-
static const int64_t MINIMAL_PERIOD_NOT_SET = -2;
372-
373-
static int64_t _minimal_period = MINIMAL_PERIOD_NOT_SET;
374-
375-
static int64_t get_minimal_period();
376369
static int64_t compute_sampling_period(double rate);
377370

378371
class JfrCPUTimeThreadSampler : public NonJavaThread {
@@ -427,7 +420,7 @@ class JfrCPUTimeThreadSampler : public NonJavaThread {
427420
bool create_timer_for_thread(JavaThread* thread, timer_t &timerid);
428421
void on_javathread_terminate(JavaThread* thread);
429422

430-
void handle_timer_signal(void* context);
423+
void handle_timer_signal(siginfo_t* info, void* context);
431424
void init_timers();
432425
void stop_timer();
433426
};
@@ -729,28 +722,31 @@ void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread *thread) {
729722

730723
void handle_timer_signal(int signo, siginfo_t* info, void* context) {
731724
assert(_instance != nullptr, "invariant");
732-
_instance->handle_timer_signal(context);
725+
_instance->handle_timer_signal(info, context);
733726
}
734727

735728

736-
void JfrCPUTimeThreadSampling::handle_timer_signal(void* context) {
729+
void JfrCPUTimeThreadSampling::handle_timer_signal(siginfo_t* info, void* context) {
737730
assert(_sampler != nullptr, "invariant");
738731
if (Atomic::load(&_sampler->_stop_signals)) {
739732
return;
740733
}
741734
Atomic::inc(&_sampler->_active_signal_handlers);
742-
_sampler->handle_timer_signal(context);
735+
_sampler->handle_timer_signal(info, context);
743736
Atomic::dec(&_sampler->_active_signal_handlers);
744737
}
745738

746-
void JfrCPUTimeThreadSampler::handle_timer_signal(void* context) {
739+
void JfrCPUTimeThreadSampler::handle_timer_signal(siginfo_t* info, void* context) {
747740
JavaThread* jt = get_java_thread_if_valid();
748741
if (jt == nullptr) {
749742
return;
750743
}
751744
JfrCPUTimeTrace* trace = this->_queues.fresh().dequeue();
752745
if (trace != nullptr) {
753-
trace->record_trace(jt, context, get_sampling_period());
746+
// the sampling period might be too low for the current Linux configuration
747+
// so samples might be skipped and we have to compute the actual period
748+
int64_t period = get_sampling_period() * (info->si_overrun + 1);
749+
trace->record_trace(jt, context, period);
754750
this->_queues.filled().enqueue(trace);
755751
} else {
756752
Atomic::inc(&_ignore_because_queue_full);
@@ -854,64 +850,11 @@ void JfrCPUTimeThreadSampler::stop_timer() {
854850
VMThread::execute(&op);
855851
}
856852

857-
// obtain the maximum frequency of CPU time events
858-
static int64_t obtain_kernel_frequency() {
859-
const int BUFFER_SIZE = 256;
860-
struct utsname uname_data;
861-
char filename[BUFFER_SIZE];
862-
char buffer[BUFFER_SIZE];
863-
char config_hz_prefix[] = "CONFIG_HZ=";
864-
FILE *file;
865-
866-
// Get kernel version using uname
867-
if (uname(&uname_data) != 0) {
868-
return -1;
869-
}
870-
871-
// Construct the filename: /boot/config-<kernel_version>
872-
snprintf(filename, sizeof(filename), "/boot/config-%s", uname_data.release);
873-
874-
// Open the file
875-
file = fopen(filename, "r");
876-
if (!file) {
877-
return -1;
878-
}
879-
880-
// Read each line and look for the CONFIG_HZ setting
881-
while (fgets(buffer, sizeof(buffer), file)) {
882-
if (strncmp(buffer, config_hz_prefix, strlen(config_hz_prefix)) == 0) {
883-
// Extract the value after "CONFIG_HZ="
884-
char *value = buffer + strlen(config_hz_prefix);
885-
int64_t hz_value = strtoll(value, NULL, 10);
886-
fclose(file);
887-
return hz_value;
888-
}
889-
}
890-
fclose(file);
891-
return -1;
892-
}
893-
894-
int64_t get_minimal_period() {
895-
if (_minimal_period == MINIMAL_PERIOD_NOT_SET) {
896-
int64_t hz = obtain_kernel_frequency();
897-
if (hz == 0) {
898-
_minimal_period = -1;
899-
} else if (hz != -1) {
900-
_minimal_period = 1000000000 / hz;
901-
}
902-
}
903-
return _minimal_period;
904-
}
905-
906853
int64_t compute_sampling_period(double rate) {
907854
if (rate == 0) {
908855
return 0;
909856
}
910-
int64_t period = os::active_processor_count() * 1000000000.0 / rate;
911-
if (get_minimal_period() > 0 && period < get_minimal_period()) {
912-
return get_minimal_period();
913-
}
914-
return period;
857+
return os::active_processor_count() * 1000000000.0 / rate;
915858
}
916859

917860
void JfrCPUTimeThreadSampler::autoadapt_period_if_needed() {

src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class JfrCPUTimeThreadSampling : public JfrCHeapObj {
5858

5959
static void on_javathread_create(JavaThread* thread);
6060
static void on_javathread_terminate(JavaThread* thread);
61-
void handle_timer_signal(void* context);
61+
void handle_timer_signal(siginfo_t* info, void* context);
6262

6363
#ifdef ASSERT
6464
static void set_process_queue(bool process_queue);

0 commit comments

Comments
 (0)