|
24 | 24 | #include "counters.h" |
25 | 25 | #include "common.h" |
26 | 26 | #include "engine.h" |
27 | | -#include "hotspot/vmStructs.h" |
| 27 | +#include "hotspot/vmStructs.inline.h" |
28 | 28 | #include "incbin.h" |
29 | 29 | #include "jvmThread.h" |
30 | 30 | #include "os.h" |
@@ -155,10 +155,13 @@ JavaCritical_com_datadoghq_profiler_JavaProfiler_filterThreadAdd0() { |
155 | 155 | slot_id = thread_filter->registerThread(); |
156 | 156 | current->setFilterSlotId(slot_id); |
157 | 157 | } |
158 | | - |
| 158 | + |
159 | 159 | if (unlikely(slot_id == -1)) { |
160 | 160 | return; // Failed to register thread |
161 | 161 | } |
| 162 | + // Reset suppression state so a new thread occupying this slot does not inherit |
| 163 | + // stale state from its predecessor. Must happen before add(). |
| 164 | + thread_filter->resetSlotRunState(slot_id); |
162 | 165 | thread_filter->add(tid, slot_id); |
163 | 166 | } |
164 | 167 |
|
@@ -314,6 +317,95 @@ Java_com_datadoghq_profiler_JavaProfiler_recordQueueEnd0( |
314 | 317 | Profiler::instance()->recordQueueTime(tid, &event); |
315 | 318 | } |
316 | 319 |
|
| 320 | +extern "C" DLLEXPORT void JNICALL |
| 321 | +Java_com_datadoghq_profiler_JavaProfiler_parkEnter0(JNIEnv *env, jclass unused) { |
| 322 | + ProfiledThread *current = ProfiledThread::current(); |
| 323 | + if (current == nullptr) { |
| 324 | + return; |
| 325 | + } |
| 326 | + bool first_park = current->parkEnter(); |
| 327 | + ThreadFilter *tf = Profiler::instance()->threadFilter(); |
| 328 | + if (first_park && tf->enabled()) { |
| 329 | + ThreadFilter::SlotID slot_id = current->filterSlotId(); |
| 330 | + if (slot_id >= 0) { |
| 331 | + current->setParkBlockToken( |
| 332 | + tf->enterBlockedRun(slot_id, OSThreadState::CONDVAR_WAIT)); |
| 333 | + } |
| 334 | + } |
| 335 | +} |
| 336 | + |
| 337 | +extern "C" DLLEXPORT void JNICALL |
| 338 | +Java_com_datadoghq_profiler_JavaProfiler_parkExit0( |
| 339 | + JNIEnv *env, jclass unused, jlong blocker, jlong unblockingSpanId) { |
| 340 | + ProfiledThread *current = ProfiledThread::current(); |
| 341 | + if (current == nullptr) { |
| 342 | + return; |
| 343 | + } |
| 344 | + u64 park_block_token = 0; |
| 345 | + if (!current->parkExit(park_block_token) || park_block_token == 0) { |
| 346 | + return; |
| 347 | + } |
| 348 | + ThreadFilter *tf = Profiler::instance()->threadFilter(); |
| 349 | + if (tf->enabled()) { |
| 350 | + ThreadFilter::SlotID slot_id = ThreadFilter::tokenSlotId(park_block_token); |
| 351 | + if (current->filterSlotId() == slot_id) { |
| 352 | + tf->exitBlockedRun(slot_id, ThreadFilter::tokenGeneration(park_block_token)); |
| 353 | + } |
| 354 | + } |
| 355 | +} |
| 356 | + |
| 357 | +static bool decodeJavaBlockState(jint state, OSThreadState &decoded) { |
| 358 | + if (state == static_cast<jint>(OSThreadState::SLEEPING)) { |
| 359 | + decoded = OSThreadState::SLEEPING; |
| 360 | + return true; |
| 361 | + } |
| 362 | + decoded = OSThreadState::UNKNOWN; |
| 363 | + return false; |
| 364 | +} |
| 365 | + |
| 366 | +extern "C" DLLEXPORT jlong JNICALL |
| 367 | +Java_com_datadoghq_profiler_JavaProfiler_blockEnter0( |
| 368 | + JNIEnv *env, jclass unused, jint state) { |
| 369 | + OSThreadState decoded; |
| 370 | + if (!decodeJavaBlockState(state, decoded)) { |
| 371 | + return 0; |
| 372 | + } |
| 373 | + ProfiledThread *current = ProfiledThread::current(); |
| 374 | + if (current == nullptr) { |
| 375 | + return 0; |
| 376 | + } |
| 377 | + ThreadFilter *tf = Profiler::instance()->threadFilter(); |
| 378 | + if (!tf->enabled()) { |
| 379 | + return 0; |
| 380 | + } |
| 381 | + ThreadFilter::SlotID slot_id = current->filterSlotId(); |
| 382 | + if (slot_id < 0) { |
| 383 | + return 0; |
| 384 | + } |
| 385 | + return static_cast<jlong>(tf->enterBlockedRun(slot_id, decoded)); |
| 386 | +} |
| 387 | + |
| 388 | +extern "C" DLLEXPORT void JNICALL |
| 389 | +Java_com_datadoghq_profiler_JavaProfiler_blockExit0( |
| 390 | + JNIEnv *env, jclass unused, jlong token) { |
| 391 | + u64 block_token = static_cast<u64>(token); |
| 392 | + if (block_token == 0) { |
| 393 | + return; |
| 394 | + } |
| 395 | + ProfiledThread *current = ProfiledThread::current(); |
| 396 | + if (current == nullptr) { |
| 397 | + return; |
| 398 | + } |
| 399 | + ThreadFilter::SlotID slot_id = ThreadFilter::tokenSlotId(block_token); |
| 400 | + if (current->filterSlotId() != slot_id) { |
| 401 | + return; |
| 402 | + } |
| 403 | + ThreadFilter *tf = Profiler::instance()->threadFilter(); |
| 404 | + if (tf->enabled()) { |
| 405 | + tf->exitBlockedRun(slot_id, ThreadFilter::tokenGeneration(block_token)); |
| 406 | + } |
| 407 | +} |
| 408 | + |
317 | 409 | extern "C" DLLEXPORT jlong JNICALL |
318 | 410 | Java_com_datadoghq_profiler_JavaProfiler_currentTicks0(JNIEnv *env, |
319 | 411 | jclass unused) { |
|
0 commit comments