4747#include < memory>
4848#include < set>
4949#include < string>
50+ #include < thread>
5051#include < vector>
5152#include < signal.h>
5253#include < stdint.h>
@@ -162,18 +163,58 @@ void Profiler::stopTaskBlockDrain() {
162163 drainTaskBlockQueue (true );
163164}
164165
165- void Profiler::drainTaskBlockQueue (bool record) {
166+ void Profiler::drainTaskBlockQueue (bool record, bool rotation_owner) {
167+ if (!rotation_owner && !tryEnterTaskBlockActivity ()) {
168+ return ;
169+ }
166170 QueuedTaskBlockEvent queued;
167171 u64 generation = _task_block_generation.load (std::memory_order_acquire);
168172 while (_task_block_queue.tryPop (queued)) {
169173 if (record && queued.generation == generation) {
170- if (recordTaskBlockLive (queued.tid , &queued.event )) {
174+ if (recordTaskBlockLiveUnchecked (queued.tid , &queued.event )) {
171175 Counters::increment (TASK_BLOCK_EMITTED );
172176 } else {
173177 Counters::increment (TASK_BLOCK_RECORD_FAILED );
174178 }
175179 }
176180 }
181+ if (!rotation_owner) {
182+ leaveTaskBlockActivity ();
183+ }
184+ }
185+
186+ bool Profiler::tryEnterTaskBlockActivity () {
187+ if (_task_block_rotation.load (std::memory_order_acquire)) {
188+ return false ;
189+ }
190+ _task_block_inflight.fetch_add (1 , std::memory_order_acq_rel);
191+ if (_task_block_rotation.load (std::memory_order_acquire)) {
192+ _task_block_inflight.fetch_sub (1 , std::memory_order_acq_rel);
193+ return false ;
194+ }
195+ return true ;
196+ }
197+
198+ void Profiler::leaveTaskBlockActivity () {
199+ _task_block_inflight.fetch_sub (1 , std::memory_order_release);
200+ }
201+
202+ void Profiler::waitForTaskBlockRotation () {
203+ while (_task_block_rotation.load (std::memory_order_acquire)) {
204+ std::this_thread::yield ();
205+ }
206+ }
207+
208+ void Profiler::beginTaskBlockRotation () {
209+ _task_block_rotation.store (true , std::memory_order_release);
210+ while (_task_block_inflight.load (std::memory_order_acquire) != 0 ) {
211+ std::this_thread::yield ();
212+ }
213+ drainTaskBlockQueue (true , true );
214+ }
215+
216+ void Profiler::endTaskBlockRotation () {
217+ _task_block_rotation.store (false , std::memory_order_release);
177218}
178219
179220void Profiler::onThreadStart (jvmtiEnv *jvmti, JNIEnv *jni, jthread thread) {
@@ -679,7 +720,9 @@ void Profiler::recordDeferredSample(int tid, u64 call_trace_id, jint event_type,
679720
680721bool Profiler::recordSample (void *ucontext, u64 counter, int tid,
681722 jint event_type, u64 call_trace_id, Event *event,
682- u64 *recorded_call_trace_id) {
723+ u64 *recorded_call_trace_id,
724+ ThreadFilter::SlotID task_block_slot_id,
725+ OSThreadState task_block_state) {
683726 atomicIncRelaxed (_total_samples);
684727
685728 u32 lock_index = getLockIndex (tid);
@@ -748,14 +791,20 @@ bool Profiler::recordSample(void *ucontext, u64 counter, int tid,
748791 if (recorded && recorded_call_trace_id != nullptr ) {
749792 *recorded_call_trace_id = call_trace_id;
750793 }
794+ if (recorded && task_block_slot_id >= 0 ) {
795+ _thread_filter.markTaskBlockSampled (task_block_slot_id, task_block_state,
796+ call_trace_id, 0 );
797+ }
751798
752799 _locks[lock_index].unlock ();
753800 return recorded;
754801}
755802
756803bool Profiler::recordSampleDelegated (void *ucontext, u64 weight, int tid,
757804 jint event_type, Event *event,
758- u64 *recorded_correlation_id) {
805+ u64 *recorded_correlation_id,
806+ ThreadFilter::SlotID task_block_slot_id,
807+ OSThreadState task_block_state) {
759808 if (!VM::canRequestStackTrace ()) {
760809 return false ;
761810 }
@@ -793,6 +842,10 @@ bool Profiler::recordSampleDelegated(void *ucontext, u64 weight, int tid,
793842 if (recorded && recorded_correlation_id != nullptr ) {
794843 *recorded_correlation_id = correlation_id;
795844 }
845+ if (recorded && task_block_slot_id >= 0 ) {
846+ _thread_filter.markTaskBlockSampled (task_block_slot_id, task_block_state,
847+ 0 , correlation_id);
848+ }
796849 _locks[lock_index].unlock ();
797850 return recorded;
798851}
@@ -830,7 +883,7 @@ void Profiler::recordQueueTime(int tid, QueueTimeEvent *event) {
830883 _locks[lock_index].unlock ();
831884}
832885
833- bool Profiler::recordTaskBlockLive (int tid, TaskBlockEvent *event) {
886+ bool Profiler::recordTaskBlockLiveUnchecked (int tid, TaskBlockEvent *event) {
834887#ifdef UNIT_TEST
835888 record_task_block_live_calls_for_test.fetch_add (1 , std::memory_order_acq_rel);
836889 last_task_block_tid_for_test.store (tid, std::memory_order_release);
@@ -852,6 +905,10 @@ bool Profiler::recordTaskBlockLive(int tid, TaskBlockEvent *event) {
852905 return recorded;
853906}
854907
908+ bool Profiler::recordTaskBlockLive (int tid, TaskBlockEvent *event) {
909+ return recordTaskBlockLiveUnchecked (tid, event);
910+ }
911+
855912bool Profiler::recordTaskBlockAsync (int tid, TaskBlockEvent *event) {
856913 if (!_task_block_drain_running.load (std::memory_order_acquire)) {
857914 Counters::increment (TASK_BLOCK_QUEUE_DROPPED );
@@ -1858,10 +1915,12 @@ Error Profiler::dump(const char *path, const int length) {
18581915 // its own writer/reader coordination; #527's classMapSharedGuard readers
18591916 // (deferred vtable receiver resolution) are coordinated through
18601917 // _class_map_lock.
1918+ beginTaskBlockRotation ();
18611919 rotateDictsAndRun ([&]{
18621920 err = _jfr.dump (path, length);
18631921 __atomic_add_fetch (&_epoch, 1 , __ATOMIC_SEQ_CST);
18641922 });
1923+ endTaskBlockRotation ();
18651924
18661925 _thread_info.clearAll (thread_ids);
18671926 _thread_info.reportCounters ();
0 commit comments