Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding in jfr thread statistics event. #20948

Merged
merged 1 commit into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions runtime/oti/j9consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,7 @@ extern "C" {
#define J9JFR_EVENT_TYPE_CLASS_LOADING_STATISTICS 7
#define J9JFR_EVENT_TYPE_THREAD_CONTEXT_SWITCH_RATE 8
#define J9JFR_EVENT_TYPE_THREAD_PARK 9
#define J9JFR_EVENT_TYPE_THREAD_STATISTICS 10

/* JFR thread states */

Expand Down
10 changes: 10 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,14 @@ typedef struct J9JFRClassLoadingStatistics {
I_64 unloadedClassCount;
} J9JFRClassLoadingStatistics;

typedef struct J9JFRThreadStatistics {
J9JFR_EVENT_COMMON_FIELDS
U_32 activeThreadCount;
U_32 daemonThreadCount;
U_32 accumulatedThreadCount;
U_32 peakThreadCount;
} J9JFRThreadStatistics;

typedef struct J9JFRThreadContextSwitchRate {
J9JFR_EVENT_COMMON_FIELDS
float switchRate;
Expand Down Expand Up @@ -5873,6 +5881,8 @@ typedef struct J9JavaVM {
UDATA anonClassCount;
UDATA totalThreadCount;
UDATA daemonThreadCount;
UDATA accumulatedThreadCount;
UDATA peakThreadCount;
omrthread_t finalizeMainThread;
omrthread_monitor_t finalizeMainMonitor;
omrthread_monitor_t processReferenceMonitor; /* the monitor for synchronizing between reference process and j9gc_wait_for_reference_processing() (only for Java 9 and later) */
Expand Down
31 changes: 31 additions & 0 deletions runtime/vm/JFRChunkWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -911,4 +911,35 @@ VM_JFRChunkWriter::writeThreadContextSwitchRateEvent(void *anElement, void *user
_bufferWriter->writeLEB128PaddedU32(dataStart, (U_32)(_bufferWriter->getCursor() - dataStart));
}

void
VM_JFRChunkWriter::writeThreadStatisticsEvent(void *anElement, void *userData)
{
ThreadStatisticsEntry *entry = (ThreadStatisticsEntry *)anElement;
VM_BufferWriter *_bufferWriter = (VM_BufferWriter *)userData;

/* reserve event size */
U_8 *dataStart = _bufferWriter->getAndIncCursor(sizeof(U_32));

/* write event type */
_bufferWriter->writeLEB128(ThreadStatisticsID);

/* write start ticks */
_bufferWriter->writeLEB128(entry->ticks);

/* write active thread count */
_bufferWriter->writeLEB128(entry->activeThreadCount);

/* write daemon thread count */
_bufferWriter->writeLEB128(entry->daemonThreadCount);

/* write accumulated thread count */
_bufferWriter->writeLEB128(entry->accumulatedThreadCount);

/* write peak thread count */
_bufferWriter->writeLEB128(entry->peakThreadCount);

/* write size */
_bufferWriter->writeLEB128PaddedU32(dataStart, _bufferWriter->getCursor() - dataStart);
}

#endif /* defined(J9VM_OPT_JFR) */
9 changes: 8 additions & 1 deletion runtime/vm/JFRChunkWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ enum MetadataTypeID {
CPULoadID = 95,
ThreadCPULoadID = 96,
ThreadContextSwitchRateID = 97,
ThreadStatisticsID = 99,
ClassLoadingStatisticsID = 100,
PhysicalMemoryID = 108,
ExecutionSampleID = 109,
Expand Down Expand Up @@ -169,6 +170,7 @@ class VM_JFRChunkWriter {
static constexpr int INITIAL_ENVIRONMENT_VARIABLE_EVENT_SIZE = 6000;
static constexpr int CLASS_LOADING_STATISTICS_EVENT_SIZE = 5 * sizeof(I_64);
static constexpr int THREAD_CONTEXT_SWITCH_RATE_SIZE = sizeof(float) + (3 * sizeof(I_64));
static constexpr int THREAD_STATISTICS_EVENT_SIZE = (6 * sizeof(U_64)) + sizeof(U_32);

static constexpr int METADATA_ID = 1;

Expand Down Expand Up @@ -350,6 +352,8 @@ class VM_JFRChunkWriter {

pool_do(_constantPoolTypes.getThreadContextSwitchRateTable(), &writeThreadContextSwitchRateEvent, _bufferWriter);

pool_do(_constantPoolTypes.getThreadStatisticsTable(), &writeThreadStatisticsEvent, _bufferWriter);

/* Only write constant events in first chunk */
if (0 == _vm->jfrState.jfrChunkCount) {
writeJVMInformationEvent();
Expand Down Expand Up @@ -597,7 +601,6 @@ class VM_JFRChunkWriter {
_bufferWriter->writeLEB128PaddedU32(dataStart, _bufferWriter->getCursor() - dataStart);
}


static void
writeCPULoadEvent(void *anElement, void *userData)
{
Expand Down Expand Up @@ -726,6 +729,8 @@ class VM_JFRChunkWriter {

static void writeThreadContextSwitchRateEvent(void *anElement, void *userData);

static void writeThreadStatisticsEvent(void *anElement, void *userData);

UDATA
calculateRequiredBufferSize()
{
Expand Down Expand Up @@ -790,6 +795,8 @@ class VM_JFRChunkWriter {

requiredBufferSize += _constantPoolTypes.getThreadContextSwitchRateCount() * THREAD_CONTEXT_SWITCH_RATE_SIZE;

requiredBufferSize += (_constantPoolTypes.getThreadStatisticsCount() * THREAD_STATISTICS_EVENT_SIZE);

return requiredBufferSize;
}

Expand Down
24 changes: 24 additions & 0 deletions runtime/vm/JFRConstantPoolTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,8 @@ VM_JFRConstantPoolTypes::addThreadParkEntry(J9JFRThreadParked* threadParkData)
entry->timeOut = threadParkData->timeOut;
entry->untilTime = threadParkData->untilTime;

_threadParkCount += 1;

done:
return;
}
Expand Down Expand Up @@ -1217,6 +1219,28 @@ VM_JFRConstantPoolTypes::addThreadContextSwitchRateEntry(J9JFRThreadContextSwitc
_threadContextSwitchRateCount += 1;
}

void
VM_JFRConstantPoolTypes::addThreadStatisticsEntry(J9JFRThreadStatistics *threadStatisticsData)
{
ThreadStatisticsEntry *entry = (ThreadStatisticsEntry *)pool_newElement(_threadStatisticsTable);

if (NULL == entry) {
_buildResult = OutOfMemory;
goto done;
}

entry->ticks = threadStatisticsData->startTicks;
entry->activeThreadCount = threadStatisticsData->activeThreadCount;
entry->daemonThreadCount = threadStatisticsData->daemonThreadCount;
entry->accumulatedThreadCount = threadStatisticsData->accumulatedThreadCount;
entry->peakThreadCount = threadStatisticsData->peakThreadCount;

_threadStatisticsCount += 1;

done:
return;
}

void
VM_JFRConstantPoolTypes::printTables()
{
Expand Down
34 changes: 34 additions & 0 deletions runtime/vm/JFRConstantPoolTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ struct ThreadContextSwitchRateEntry {
float switchRate;
};

struct ThreadStatisticsEntry {
I_64 ticks;
U_32 activeThreadCount;
U_32 daemonThreadCount;
U_32 accumulatedThreadCount;
U_32 peakThreadCount;
};

struct JVMInformationEntry {
const char *jvmName;
const char *jvmVersion;
Expand Down Expand Up @@ -338,6 +346,8 @@ class VM_JFRConstantPoolTypes {
UDATA _classLoadingStatisticsCount;
J9Pool *_threadContextSwitchRateTable;
U_32 _threadContextSwitchRateCount;
J9Pool *_threadStatisticsTable;
UDATA _threadStatisticsCount;

/* Processing buffers */
StackFrame *_currentStackFrameBuffer;
Expand Down Expand Up @@ -611,6 +621,8 @@ class VM_JFRConstantPoolTypes {

void addThreadContextSwitchRateEntry(J9JFRThreadContextSwitchRate *threadContextSwitchRateData);

void addThreadStatisticsEntry(J9JFRThreadStatistics *threadStatisticsData);

J9Pool *getExecutionSampleTable()
{
return _executionSampleTable;
Expand Down Expand Up @@ -661,6 +673,11 @@ class VM_JFRConstantPoolTypes {
return _threadContextSwitchRateTable;
}

J9Pool *getThreadStatisticsTable()
{
return _threadStatisticsTable;
}

UDATA getExecutionSampleCount()
{
return _executionSampleCount;
Expand Down Expand Up @@ -711,6 +728,11 @@ class VM_JFRConstantPoolTypes {
return _threadContextSwitchRateCount;
}

UDATA getThreadStatisticsCount()
{
return _threadStatisticsCount;
}

ClassloaderEntry *getClassloaderEntry()
{
return _firstClassloaderEntry;
Expand Down Expand Up @@ -869,6 +891,9 @@ class VM_JFRConstantPoolTypes {
case J9JFR_EVENT_TYPE_THREAD_CONTEXT_SWITCH_RATE:
addThreadContextSwitchRateEntry((J9JFRThreadContextSwitchRate *)event);
break;
case J9JFR_EVENT_TYPE_THREAD_STATISTICS:
addThreadStatisticsEntry((J9JFRThreadStatistics *)event);
break;
default:
Assert_VM_unreachable();
break;
Expand Down Expand Up @@ -1201,6 +1226,8 @@ class VM_JFRConstantPoolTypes {
, _classLoadingStatisticsCount(0)
, _threadContextSwitchRateTable(NULL)
, _threadContextSwitchRateCount(0)
, _threadStatisticsTable(NULL)
, _threadStatisticsCount(0)
, _previousStackTraceEntry(NULL)
, _firstStackTraceEntry(NULL)
, _previousThreadEntry(NULL)
Expand Down Expand Up @@ -1333,6 +1360,12 @@ class VM_JFRConstantPoolTypes {
goto done;
}

_threadStatisticsTable = pool_new(sizeof(ThreadStatisticsEntry), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary));
if (NULL == _threadStatisticsTable ) {
_buildResult = OutOfMemory;
goto done;
}

/* Add reserved index for default entries. For strings zero is the empty or NUll string.
* For package zero is the deafult package, for Module zero is the unnamed module. ThreadGroup
* zero is NULL threadGroup.
Expand Down Expand Up @@ -1424,6 +1457,7 @@ class VM_JFRConstantPoolTypes {
pool_kill(_threadCPULoadTable);
pool_kill(_classLoadingStatisticsTable);
pool_kill(_threadContextSwitchRateTable);
pool_kill(_threadStatisticsTable);
j9mem_free_memory(_globalStringTable);
}

Expand Down
21 changes: 21 additions & 0 deletions runtime/vm/jfr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ jfrEventSize(J9JFREvent *jfrEvent)
case J9JFR_EVENT_TYPE_THREAD_CONTEXT_SWITCH_RATE:
size = sizeof(J9JFRThreadContextSwitchRate);
break;
case J9JFR_EVENT_TYPE_THREAD_STATISTICS:
size = sizeof(J9JFRThreadStatistics);
break;
default:
Assert_VM_unreachable();
break;
Expand Down Expand Up @@ -1078,6 +1081,23 @@ jfrThreadContextSwitchRate(J9VMThread *currentThread)
}
}

void
jfrThreadStatistics(J9VMThread *currentThread)
{
J9JavaVM *vm = currentThread->javaVM;
J9JFRThreadStatistics *jfrEvent = (J9JFRThreadStatistics *)reserveBuffer(currentThread, sizeof(J9JFRThreadStatistics));

if (NULL != jfrEvent) {
initializeEventFields(currentThread, (J9JFREvent *)jfrEvent, J9JFR_EVENT_TYPE_THREAD_STATISTICS);

jfrEvent->activeThreadCount = vm->totalThreadCount;
jfrEvent->daemonThreadCount = vm->daemonThreadCount;
jfrEvent->accumulatedThreadCount = vm->accumulatedThreadCount;
jfrEvent->peakThreadCount = vm->peakThreadCount;
}

}

static int J9THREAD_PROC
jfrSamplingThreadProc(void *entryArg)
{
Expand All @@ -1096,6 +1116,7 @@ jfrSamplingThreadProc(void *entryArg)
internalAcquireVMAccess(currentThread);
jfrCPULoad(currentThread);
jfrClassLoadingStatistics(currentThread);
jfrThreadStatistics(currentThread);
if (0 == (count % 1000)) { // 10 seconds
J9SignalAsyncEvent(vm, NULL, vm->jfrThreadCPULoadAsyncKey);
jfrThreadContextSwitchRate(currentThread);
Expand Down
5 changes: 5 additions & 0 deletions runtime/vm/vmthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ allocateVMThread(J9JavaVM *vm, omrthread_t osThread, UDATA privateFlags, void *m
/* Update counters for total # of threads and daemon threads and notify anyone waiting */

++(vm->totalThreadCount);
++(vm->accumulatedThreadCount);
if (vm->totalThreadCount > vm->peakThreadCount) {
vm->peakThreadCount = vm->totalThreadCount;
}

if (privateFlags & J9_PRIVATE_FLAGS_DAEMON_THREAD) {
++(vm->daemonThreadCount);
}
Expand Down