|
45 | 45 | #include "runtime/vmThread.hpp" |
46 | 46 |
|
47 | 47 | #include "signals_posix.hpp" |
48 | | -#include <sys/utsname.h> |
49 | 48 |
|
50 | 49 | static const int64_t AUTOADAPT_INTERVAL_MS = 100; |
51 | 50 |
|
@@ -367,12 +366,6 @@ class JfrTraceQueues { |
367 | 366 | } |
368 | 367 | }; |
369 | 368 |
|
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(); |
376 | 369 | static int64_t compute_sampling_period(double rate); |
377 | 370 |
|
378 | 371 | class JfrCPUTimeThreadSampler : public NonJavaThread { |
@@ -427,7 +420,7 @@ class JfrCPUTimeThreadSampler : public NonJavaThread { |
427 | 420 | bool create_timer_for_thread(JavaThread* thread, timer_t &timerid); |
428 | 421 | void on_javathread_terminate(JavaThread* thread); |
429 | 422 |
|
430 | | - void handle_timer_signal(void* context); |
| 423 | + void handle_timer_signal(siginfo_t* info, void* context); |
431 | 424 | void init_timers(); |
432 | 425 | void stop_timer(); |
433 | 426 | }; |
@@ -729,28 +722,31 @@ void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread *thread) { |
729 | 722 |
|
730 | 723 | void handle_timer_signal(int signo, siginfo_t* info, void* context) { |
731 | 724 | assert(_instance != nullptr, "invariant"); |
732 | | - _instance->handle_timer_signal(context); |
| 725 | + _instance->handle_timer_signal(info, context); |
733 | 726 | } |
734 | 727 |
|
735 | 728 |
|
736 | | -void JfrCPUTimeThreadSampling::handle_timer_signal(void* context) { |
| 729 | +void JfrCPUTimeThreadSampling::handle_timer_signal(siginfo_t* info, void* context) { |
737 | 730 | assert(_sampler != nullptr, "invariant"); |
738 | 731 | if (Atomic::load(&_sampler->_stop_signals)) { |
739 | 732 | return; |
740 | 733 | } |
741 | 734 | Atomic::inc(&_sampler->_active_signal_handlers); |
742 | | - _sampler->handle_timer_signal(context); |
| 735 | + _sampler->handle_timer_signal(info, context); |
743 | 736 | Atomic::dec(&_sampler->_active_signal_handlers); |
744 | 737 | } |
745 | 738 |
|
746 | | -void JfrCPUTimeThreadSampler::handle_timer_signal(void* context) { |
| 739 | +void JfrCPUTimeThreadSampler::handle_timer_signal(siginfo_t* info, void* context) { |
747 | 740 | JavaThread* jt = get_java_thread_if_valid(); |
748 | 741 | if (jt == nullptr) { |
749 | 742 | return; |
750 | 743 | } |
751 | 744 | JfrCPUTimeTrace* trace = this->_queues.fresh().dequeue(); |
752 | 745 | 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); |
754 | 750 | this->_queues.filled().enqueue(trace); |
755 | 751 | } else { |
756 | 752 | Atomic::inc(&_ignore_because_queue_full); |
@@ -854,64 +850,11 @@ void JfrCPUTimeThreadSampler::stop_timer() { |
854 | 850 | VMThread::execute(&op); |
855 | 851 | } |
856 | 852 |
|
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 | | - |
906 | 853 | int64_t compute_sampling_period(double rate) { |
907 | 854 | if (rate == 0) { |
908 | 855 | return 0; |
909 | 856 | } |
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; |
915 | 858 | } |
916 | 859 |
|
917 | 860 | void JfrCPUTimeThreadSampler::autoadapt_period_if_needed() { |
|
0 commit comments