@@ -70,7 +70,8 @@ class JniString {
7070};
7171
7272extern " C" DLLEXPORT jboolean JNICALL
73- Java_com_datadoghq_profiler_JavaProfiler_init0 (JNIEnv *env, jclass unused) {
73+ Java_com_datadoghq_profiler_JavaProfiler_init0 (
74+ JNIEnv *env, jclass unused, jboolean delegateMonitorWaitEvents) {
7475 Error error = Profiler::instance ()->init ();
7576 if (error) {
7677 throwNew (env, " java/lang/IllegalStateException" , error.message ());
@@ -79,13 +80,22 @@ Java_com_datadoghq_profiler_JavaProfiler_init0(JNIEnv *env, jclass unused) {
7980
8081
8182 // JavaVM* has already been stored when the native library was loaded so we can pass nullptr here
82- if (VM::initProfilerBridge (nullptr , true )) {
83- // Attach ProfiledThread
84- ProfiledThread::initCurrentThreadSignalSafe ();
85- return JNI_TRUE ;
86- } else {
83+ ProfilerBridgeInitResult result =
84+ VM::initProfilerBridge (nullptr , true , delegateMonitorWaitEvents);
85+ if (result == ProfilerBridgeInitResult::MONITOR_EVENTS_DELEGATION_CONFLICT ) {
86+ throwNew (env, " java/lang/IllegalStateException" ,
87+ " Monitor-event ownership conflicts with the profiler's "
88+ " process-wide initialization" );
8789 return JNI_FALSE ;
8890 }
91+ if (result != ProfilerBridgeInitResult::SUCCESS ) {
92+ throwNew (env, " java/lang/IllegalStateException" ,
93+ " Failed to initialize the profiler bridge" );
94+ return JNI_FALSE ;
95+ }
96+ // Attach ProfiledThread
97+ ProfiledThread::initCurrentThreadSignalSafe ();
98+ return JNI_TRUE ;
8999}
90100
91101extern " C" DLLEXPORT void JNICALL
@@ -110,6 +120,12 @@ Java_com_datadoghq_profiler_JavaProfiler_getTid0(JNIEnv *env, jclass unused) {
110120 return OS::threadId ();
111121}
112122
123+ extern " C" DLLEXPORT jboolean JNICALL
124+ Java_com_datadoghq_profiler_JavaProfiler_monitorWaitEventsDelegated0 (
125+ JNIEnv *env, jclass unused) {
126+ return VM::monitorWaitEventsDelegated ();
127+ }
128+
113129extern " C" DLLEXPORT jstring JNICALL
114130Java_com_datadoghq_profiler_JavaProfiler_execute0 (JNIEnv *env, jobject unused,
115131 jstring command) {
@@ -389,44 +405,55 @@ Java_com_datadoghq_profiler_JavaProfiler_recordQueueEnd0(
389405}
390406
391407extern " C" DLLEXPORT jboolean JNICALL
392- Java_com_datadoghq_profiler_JavaProfiler_parkEnter0 (JNIEnv *env, jclass unused) {
408+ Java_com_datadoghq_profiler_JavaProfiler_parkEnter0 (
409+ JNIEnv *env, jclass unused, jthread thread) {
410+ if (!JVMSupport::isPlatformThread (env, thread)) {
411+ return JNI_FALSE ;
412+ }
393413 ProfiledThread *current = ProfiledThread::initCurrentThreadSignalSafe ();
394414 if (current == nullptr ) {
395415 return JNI_FALSE ;
396416 }
417+ Context context = ContextApi::snapshot ();
418+ if (!current->parkEnter (TSC::ticks (), context)) {
419+ return JNI_FALSE ;
420+ }
397421
398- bool first_park = current->parkEnter ();
399- ThreadFilter *tf = Profiler::instance ()->threadFilter ();
400- if (first_park && tf->registryActive ()) {
422+ Profiler *profiler = Profiler::instance ();
423+ ThreadFilter *tf = profiler->threadFilter ();
424+ if (context.spanId == 0 && tf->registryActive () &&
425+ (profiler->taskBlockEnabled () || tf->enabled ())) {
401426 ThreadFilter::SlotID slot_id = tf->ensureCurrentThreadSlot (current);
402427 if (slot_id >= 0 ) {
403- current->setParkBlockToken (
404- tf-> enterBlockedRun ( slot_id, OSThreadState::CONDVAR_WAIT ));
428+ current->setParkBlockToken (tf-> enterBlockedRun (
429+ slot_id, OSThreadState::CONDVAR_WAIT , BlockRunOwner:: JAVA ));
405430 }
406431 }
407- return first_park ? JNI_TRUE : JNI_FALSE ;
432+ return JNI_TRUE ;
408433}
409434
410435extern " C" DLLEXPORT void JNICALL
411436Java_com_datadoghq_profiler_JavaProfiler_parkExit0 (
412- JNIEnv *env, jclass unused, jlong blocker, jlong unblockingSpanId) {
437+ JNIEnv *env, jclass unused, jthread thread, jlong blocker,
438+ jlong unblockingSpanId) {
439+ if (!JVMSupport::isPlatformThread (env, thread)) {
440+ return ;
441+ }
413442 ProfiledThread *current = ProfiledThread::initCurrentThreadSignalSafe ();
414443 if (current == nullptr ) {
415444 return ;
416445 }
417-
446+ u64 start_ticks = 0 ;
418447 u64 park_block_token = 0 ;
419- if (!current->parkExit (park_block_token) || park_block_token == 0 ) {
448+ Context context{};
449+ if (!current->parkExit (start_ticks, context, park_block_token) ||
450+ park_block_token == 0 ) {
420451 return ;
421452 }
422- ThreadFilter *tf = Profiler::instance ()->threadFilter ();
423- if (tf->registryActive ()) {
424- ThreadFilter::SlotID slot_id = ThreadFilter::tokenSlotId (park_block_token);
425- if (tf->activeSlotForId (current->filterSlotId (), current->tid ()) != nullptr &&
426- current->filterSlotId () == slot_id) {
427- tf->exitBlockedRun (slot_id, ThreadFilter::tokenGeneration (park_block_token));
428- }
429- }
453+ finishTaskBlockAtExit (current, Profiler::instance ()->threadFilter (), thread,
454+ 1 , park_block_token, start_ticks, context,
455+ static_cast <u64 >(blocker),
456+ static_cast <u64 >(unblockingSpanId));
430457}
431458
432459static bool decodeJavaBlockState (jint state, OSThreadState &decoded) {
@@ -454,13 +481,14 @@ static bool isCurrentJniThread(JNIEnv* env, jthread thread) {
454481
455482extern " C" DLLEXPORT jlong JNICALL
456483Java_com_datadoghq_profiler_JavaProfiler_blockEnter0 (
457- JNIEnv *env, jclass unused, jint state) {
458- ProfiledThread *current = ProfiledThread::initCurrentThreadSignalSafe ();
459- if (current == nullptr ) {
484+ JNIEnv *env, jclass unused, jthread thread, jint state) {
485+ OSThreadState decoded;
486+ if (!decodeJavaBlockState (state, decoded) ||
487+ !JVMSupport::isPlatformThread (env, thread)) {
460488 return 0 ;
461489 }
462- OSThreadState decoded ;
463- if (! decodeJavaBlockState (state, decoded) ) {
490+ ProfiledThread *current = ProfiledThread::initCurrentThreadSignalSafe () ;
491+ if (current == nullptr ) {
464492 return 0 ;
465493 }
466494 u64 span_id = 0 , root_span_id = 0 ;
@@ -480,9 +508,9 @@ Java_com_datadoghq_profiler_JavaProfiler_blockEnter0(
480508
481509extern " C" DLLEXPORT void JNICALL
482510Java_com_datadoghq_profiler_JavaProfiler_blockExit0 (
483- JNIEnv *env, jclass unused, jlong token) {
511+ JNIEnv *env, jclass unused, jthread thread, jlong token) {
484512 u64 block_token = static_cast <u64 >(token);
485- if (block_token == 0 ) {
513+ if (block_token == 0 || ! JVMSupport::isPlatformThread (env, thread) ) {
486514 return ;
487515 }
488516
0 commit comments