@@ -78,7 +78,20 @@ Java_com_datadoghq_profiler_JavaProfiler_init0(
7878 }
7979
8080 // JavaVM* has already been stored when the native library was loaded so we can pass nullptr here
81- return VM::initProfilerBridge (nullptr , true , delegateMonitorWaitEvents);
81+ ProfilerBridgeInitResult result =
82+ VM::initProfilerBridge (nullptr , true , delegateMonitorWaitEvents);
83+ if (result == ProfilerBridgeInitResult::MONITOR_EVENTS_DELEGATION_CONFLICT ) {
84+ throwNew (env, " java/lang/IllegalStateException" ,
85+ " Monitor-event ownership conflicts with the profiler's "
86+ " process-wide initialization" );
87+ return JNI_FALSE ;
88+ }
89+ if (result != ProfilerBridgeInitResult::SUCCESS ) {
90+ throwNew (env, " java/lang/IllegalStateException" ,
91+ " Failed to initialize the profiler bridge" );
92+ return JNI_FALSE ;
93+ }
94+ return JNI_TRUE ;
8295}
8396
8497extern " C" DLLEXPORT void JNICALL
@@ -144,32 +157,6 @@ Java_com_datadoghq_profiler_JavaProfiler_getSamples(JNIEnv *env,
144157 return (jlong)Profiler::instance ()->total_samples ();
145158}
146159
147- // some duplication between add and remove, though we want to avoid having an extra branch in the hot path
148-
149- static ThreadFilter::SlotID ensureCurrentThreadFilterSlot (
150- ThreadFilter *thread_filter, ProfiledThread *current) {
151- int tid = current->tid ();
152- if (unlikely (tid < 0 )) {
153- return -1 ;
154- }
155-
156- ThreadFilter::SlotID slot_id = current->filterSlotId ();
157- if (likely (slot_id >= 0 )) {
158- if (likely (thread_filter->activeSlotForId (slot_id, tid) != nullptr )) {
159- return slot_id;
160- }
161- current->setFilterSlotId (-1 );
162- }
163-
164- // Startup can register this TID centrally, but it cannot update another
165- // pthread's TLS. registerThread(tid) reuses that existing slot.
166- slot_id = thread_filter->registerThread (tid);
167- if (slot_id >= 0 ) {
168- current->setFilterSlotId (slot_id);
169- }
170- return slot_id;
171- }
172-
173160// JavaCritical is faster JNI, but more restrictive - parameters and return value have to be
174161// primitives or arrays of primitive types.
175162// We direct corresponding JNI calls to JavaCritical to make sure the parameters/return value
@@ -191,7 +178,7 @@ JavaCritical_com_datadoghq_profiler_JavaProfiler_filterThreadAdd0() {
191178 return ;
192179 }
193180
194- int slot_id = ensureCurrentThreadFilterSlot ( thread_filter, current);
181+ int slot_id = thread_filter-> ensureCurrentThreadSlot ( current);
195182 if (unlikely (slot_id < 0 )) {
196183 return ; // Failed to register thread
197184 }
@@ -385,7 +372,7 @@ Java_com_datadoghq_profiler_JavaProfiler_parkEnter0(
385372 ThreadFilter *tf = profiler->threadFilter ();
386373 if (context.spanId == 0 && tf->registryActive () &&
387374 (profiler->taskBlockEnabled () || tf->enabled ())) {
388- ThreadFilter::SlotID slot_id = ensureCurrentThreadFilterSlot (tf, current);
375+ ThreadFilter::SlotID slot_id = tf-> ensureCurrentThreadSlot ( current);
389376 if (slot_id >= 0 ) {
390377 current->setParkBlockToken (tf->enterBlockedRun (
391378 slot_id, OSThreadState::CONDVAR_WAIT , BlockRunOwner::JAVA ));
@@ -412,32 +399,10 @@ Java_com_datadoghq_profiler_JavaProfiler_parkExit0(
412399 return ;
413400 }
414401 Profiler *profiler = Profiler::instance ();
415- bool recording_enabled = profiler->taskBlockEnabled ();
416- bool activity = profiler->tryEnterTaskBlockActivity ();
417- if (!activity) profiler->waitForTaskBlockRotation ();
418-
419- ThreadFilter *tf = profiler->threadFilter ();
420- ThreadFilter::SlotID slot_id = ThreadFilter::tokenSlotId (park_block_token);
421- ThreadFilter::SlotID current_slot = current->filterSlotId ();
422- if (current_slot < 0 ) current_slot = tf->slotIdByTid (current->tid ());
423- BlockRunSnapshot snapshot{};
424- bool exited = current_slot == slot_id &&
425- tf->snapshotAndExitBlockedRun (
426- slot_id, ThreadFilter::tokenGeneration (park_block_token), &snapshot);
427-
428- if (!activity) {
429- Counters::increment (TASK_BLOCK_DROPPED_ROTATION );
430- return ;
431- }
432- if (recording_enabled && exited && snapshot.context_eligible ) {
433- recordTaskBlockIfEligible (
434- current->tid (), thread, 1 , start_ticks, TSC::ticks (), context,
435- static_cast <u64 >(blocker), static_cast <u64 >(unblockingSpanId),
436- snapshot.active_state , true );
437- } else if (recording_enabled && exited && !snapshot.context_eligible ) {
438- Counters::increment (TASK_BLOCK_SKIPPED_TRACE_CONTEXT );
439- }
440- profiler->leaveTaskBlockActivity ();
402+ finishTaskBlockAtExit (
403+ current, profiler->threadFilter (), thread, 1 , park_block_token,
404+ start_ticks, context, static_cast <u64 >(blocker),
405+ static_cast <u64 >(unblockingSpanId));
441406}
442407
443408static bool decodeJavaBlockState (jint state, OSThreadState &decoded) {
@@ -469,7 +434,7 @@ Java_com_datadoghq_profiler_JavaProfiler_blockEnter0(
469434 if (!profiler->taskBlockEnabled () && !tf->enabled ()) {
470435 return 0 ;
471436 }
472- ThreadFilter::SlotID slot_id = ensureCurrentThreadFilterSlot (tf, current);
437+ ThreadFilter::SlotID slot_id = tf-> ensureCurrentThreadSlot ( current);
473438 if (slot_id < 0 ) return 0 ;
474439 return static_cast <jlong>(tf->enterBlockedRun (slot_id, decoded));
475440}
@@ -510,7 +475,7 @@ Java_com_datadoghq_profiler_JavaProfiler_beginTaskBlock0(
510475 }
511476 ThreadFilter *tf = profiler->threadFilter ();
512477 if (!tf->unfilteredWallTrackingActive ()) return 0 ;
513- ThreadFilter::SlotID slot_id = ensureCurrentThreadFilterSlot (tf, current);
478+ ThreadFilter::SlotID slot_id = tf-> ensureCurrentThreadSlot ( current);
514479 if (slot_id < 0 ) return 0 ;
515480
516481 Context context = ContextApi::snapshot ();
0 commit comments