On Wed, 4 Jun 2025 12:56:22 GMT, Johannes Bechberger <jbechber...@openjdk.org> wrote:
>> This is the code for the [JEP 509: CPU Time based profiling for >> JFR](https://openjdk.org/jeps/509). >> >> Currently tested using [this test >> suite](https://github.com/parttimenerd/basic-profiler-tests). This runs >> profiles the [Renaissance](https://renaissance.dev/) benchmark with >> - ... different heap sizes >> - ... different GCs >> - ... different samplers (the standard JFR and the new CPU Time Sampler and >> both) >> - ... different JFR recording durations >> - ... different chunk-sizes > > Johannes Bechberger has updated the pull request incrementally with one > additional commit since the last revision: > > Fix build I took a look at this. I only found one issue that needs fixing before integration and then a few comments. Thanks. src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 59: > 57: Thread* raw_thread = Thread::current_or_null_safe(); > 58: if (raw_thread == nullptr) { > 59: // probably while shutting down Do you remember which test fail because of this? It would be interesting to know, since I don’t see how it could be null here. src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 330: > 328: void JfrCPUSamplerThread::stackwalk_threads_in_native() { > 329: ResourceMark rm; > 330: MutexLocker tlock(Threads_lock); What exactly are we guarding against by holding the `Threads_lock`? Seems `ThreadsListHandle` should be enough. src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 430: > 428: void JfrCPUTimeThreadSampling::create_sampler(double rate, bool > auto_adapt) { > 429: assert(_sampler == nullptr, "invariant"); > 430: _sampler = new JfrCPUSamplerThread(rate, auto_adapt); If we start a recording on an already running process we have a race here where a new thread can create and set its timer before we call init_timers() where the signal handler is installed. In that case the program will terminate with message “Profiling timer expired" (default action for SIGPROF). It can be easily reproduced by adding a delay here and starting a recording on a simple test that just creates new threads. We need to add some extra check in create_timer_for_thread() or install the signal handler earlier. src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 584: > 582: sev.sigev_notify = SIGEV_THREAD_ID; > 583: sev.sigev_signo = SIG; > 584: sev.sigev_value.sival_ptr = &t; Why setting the address of `t` which is a local variable here? ------------- PR Review: https://git.openjdk.org/jdk/pull/25302#pullrequestreview-2896813404 PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126661443 PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126670024 PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126651264 PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126666505